summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/feh.pre20
-rw-r--r--share/applications/feh.pre4
-rw-r--r--src/imlib.c108
-rw-r--r--src/options.c10
-rw-r--r--src/options.h1
-rw-r--r--src/slideshow.c76
6 files changed, 138 insertions, 81 deletions
diff --git a/man/feh.pre b/man/feh.pre
index f019811..31817cc 100644
--- a/man/feh.pre
+++ b/man/feh.pre
@@ -578,6 +578,19 @@ Disable slideshow mode.
With this setting, instead of opening multiple files in slideshow mode,
multiple windows will be opened; one per file.
.
+.It Cm --no-conversion-cache
+.
+When loading images via HTTP, ImageMagick or dcraw,
+.Nm
+will only load/convert them once and re-use the cached file on subsequent
+slideshow passes.
+This option disables the cache. It is also disabled when
+.Cm --reload
+is used.
+Use it if you rely on frequently changing files loaded via one of these
+sources.
+Note that it will impair performance.
+.
.It Cm --no-jump-on-resort
.
Don't jump to the first image after resorting the filelist.
@@ -791,6 +804,13 @@ keys to browse through the directory.
See
.Sx USAGE EXAMPLES
for examples.
+If
+.Ar filename
+is a URL and no files or filelists were specified,
+.Nm
+will show
+.Ar filename
+and not attempt to load additional files or directories.
.
.Pp
.
diff --git a/share/applications/feh.pre b/share/applications/feh.pre
index e5efc5b..fe23468 100644
--- a/share/applications/feh.pre
+++ b/share/applications/feh.pre
@@ -4,10 +4,10 @@ Name[en_US]=feh
GenericName=Image viewer
GenericName[en_US]=Image viewer
Comment=Image viewer and cataloguer
-Exec=feh --start-at %f
+Exec=feh --start-at %u
Terminal=false
Type=Application
Icon=feh
Categories=Graphics;2DGraphics;Viewer;
-MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-bmp;image/x-pcx;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-tga;image/x-xbitmap;
+MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/webp;image/x-bmp;image/x-pcx;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-tga;image/x-xbitmap;
NoDisplay=true
diff --git a/src/imlib.c b/src/imlib.c
index b9f071a..2eeb37d 100644
--- a/src/imlib.c
+++ b/src/imlib.c
@@ -60,6 +60,11 @@ int xinerama_screen;
int num_xinerama_screens;
#endif /* HAVE_LIBXINERAMA */
+#ifdef HAVE_LIBCURL
+// TODO use cache for dcraw and magick conversion results as well
+gib_hash* http_cache = NULL;
+#endif
+
int childpid = 0;
static int feh_file_is_raw(char *filename);
@@ -258,10 +263,15 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
file->ed = exif_get_data(tmpname);
#endif
}
- if ((image_source != SRC_HTTP) || !opt.keep_http)
+ if ((image_source != SRC_HTTP) || (!opt.keep_http && !opt.use_http_cache))
unlink(tmpname);
+ // keep_http already performs an add_file_to_rm_filelist call
+ else if (opt.use_http_cache && !opt.keep_http)
+ // add_file_to_rm_filelist duplicates tmpname
+ add_file_to_rm_filelist(tmpname);
- free(tmpname);
+ if (image_source != SRC_HTTP && !opt.use_http_cache)
+ free(tmpname);
}
if ((err) || (!im)) {
@@ -319,6 +329,91 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
return(1);
}
+void feh_reload_image(winwidget w, int resize, int force_new)
+{
+ char *new_title;
+ int len;
+ Imlib_Image tmp;
+ int old_w, old_h;
+
+ if (!w->file) {
+ im_weprintf(w, "couldn't reload, this image has no file associated with it.");
+ winwidget_render_image(w, 0, 0);
+ return;
+ }
+
+ D(("resize %d, force_new %d\n", resize, force_new));
+
+ free(FEH_FILE(w->file->data)->caption);
+ FEH_FILE(w->file->data)->caption = NULL;
+
+ len = strlen(w->name) + sizeof("Reloading: ") + 1;
+ new_title = emalloc(len);
+ snprintf(new_title, len, "Reloading: %s", w->name);
+ winwidget_rename(w, new_title);
+ free(new_title);
+
+ old_w = gib_imlib_image_get_width(w->im);
+ old_h = gib_imlib_image_get_height(w->im);
+
+ /*
+ * If we don't free the old image before loading the new one, Imlib2's
+ * caching will get in our way.
+ * However, if --reload is used (force_new == 0), we want to continue if
+ * the new image cannot be loaded, so we must not free the old image yet.
+ */
+ if (force_new)
+ winwidget_free_image(w);
+
+#ifdef HAVE_LIBCURL
+ // if it's an external image, our own cache will also get in your way
+ char *sfn;
+ if (opt.use_http_cache && (sfn = gib_hash_get(http_cache, FEH_FILE(w->file->data)->filename)) != NULL) {
+ free(sfn);
+ gib_hash_set(http_cache, FEH_FILE(w->file->data)->filename, NULL);
+ }
+#endif
+
+ if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) {
+ if (force_new)
+ eprintf("failed to reload image\n");
+ else {
+ im_weprintf(w, "Couldn't reload image. Is it still there?");
+ winwidget_render_image(w, 0, 0);
+ }
+ return;
+ }
+
+ if (!resize && ((old_w != gib_imlib_image_get_width(tmp)) ||
+ (old_h != gib_imlib_image_get_height(tmp))))
+ resize = 1;
+
+ if (!force_new)
+ winwidget_free_image(w);
+
+ w->im = tmp;
+ winwidget_reset_image(w);
+
+ w->mode = MODE_NORMAL;
+ if ((w->im_w != gib_imlib_image_get_width(w->im))
+ || (w->im_h != gib_imlib_image_get_height(w->im)))
+ w->had_resize = 1;
+ if (w->has_rotated) {
+ Imlib_Image temp;
+
+ temp = gib_imlib_create_rotated_image(w->im, 0.0);
+ w->im_w = gib_imlib_image_get_width(temp);
+ w->im_h = gib_imlib_image_get_height(temp);
+ gib_imlib_free_image_and_decache(temp);
+ } else {
+ w->im_w = gib_imlib_image_get_width(w->im);
+ w->im_h = gib_imlib_image_get_height(w->im);
+ }
+ winwidget_render_image(w, resize, 0);
+
+ return;
+}
+
static int feh_file_is_raw(char *filename)
{
childpid = fork();
@@ -576,6 +671,13 @@ static char *feh_http_load_image(char *url)
char *basename;
char *path = NULL;
+ if (opt.use_http_cache) {
+ if (!http_cache)
+ http_cache = gib_hash_new();
+ if ((sfn = gib_hash_get(http_cache, url)) != NULL)
+ return sfn;
+ }
+
if (opt.keep_http) {
if (opt.output_dir)
path = opt.output_dir;
@@ -648,6 +750,8 @@ static char *feh_http_load_image(char *url)
free(ebuff);
fclose(sfp);
+ if (opt.use_http_cache)
+ gib_hash_set(http_cache, url, sfn);
return sfn;
} else {
weprintf("open url: fdopen failed:");
diff --git a/src/options.c b/src/options.c
index d3c1d52..eb0fbe5 100644
--- a/src/options.c
+++ b/src/options.c
@@ -76,6 +76,7 @@ void init_parse_options(int argc, char **argv)
#ifdef HAVE_INOTIFY
opt.auto_reload = 1;
#endif /* HAVE_INOTIFY */
+ opt.use_http_cache = 1;
feh_getopt_theme(argc, argv);
@@ -431,6 +432,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
{"auto-reload" , 0, 0, 248},
#endif
{"class" , 1, 0, 249},
+ {"no-conversion-cache", 0, 0, 250},
{0, 0, 0, 0}
};
int optch = 0, cmdx = 0;
@@ -523,6 +525,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
break;
case 'R':
opt.reload = atof(optarg);
+ opt.use_http_cache = 0;
#ifdef HAVE_INOTIFY
opt.auto_reload = 0;
#endif
@@ -827,6 +830,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
case 249:
opt.x11_class = estrdup(optarg);
break;
+ case 250:
+ opt.use_http_cache = 0;
+ break;
default:
break;
}
@@ -843,7 +849,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
}
}
else if (finalrun && !opt.filelistfile && !opt.bgmode) {
- if (opt.start_list_at && !path_is_url(opt.start_list_at) && strrchr(opt.start_list_at, '/')) {
+ if (opt.start_list_at && path_is_url(opt.start_list_at)) {
+ add_file_to_filelist_recursively(opt.start_list_at, FILELIST_FIRST);
+ } else if (opt.start_list_at && strrchr(opt.start_list_at, '/')) {
char *target_directory = estrdup(opt.start_list_at);
char *filename_start = strrchr(target_directory, '/');
if (filename_start) {
diff --git a/src/options.h b/src/options.h
index 93474a9..74ef33f 100644
--- a/src/options.h
+++ b/src/options.h
@@ -49,6 +49,7 @@ struct __fehoptions {
unsigned char aspect;
unsigned char stretch;
unsigned char keep_http;
+ unsigned char use_http_cache;
unsigned char borderless;
unsigned char randomize;
unsigned char jump_on_resort;
diff --git a/src/slideshow.c b/src/slideshow.c
index ac8c545..f807d41 100644
--- a/src/slideshow.c
+++ b/src/slideshow.c
@@ -182,82 +182,6 @@ void cb_reload_timer(void *data)
return;
}
-void feh_reload_image(winwidget w, int resize, int force_new)
-{
- char *new_title;
- int len;
- Imlib_Image tmp;
- int old_w, old_h;
-
- if (!w->file) {
- im_weprintf(w, "couldn't reload, this image has no file associated with it.");
- winwidget_render_image(w, 0, 0);
- return;
- }
-
- D(("resize %d, force_new %d\n", resize, force_new));
-
- free(FEH_FILE(w->file->data)->caption);
- FEH_FILE(w->file->data)->caption = NULL;
-
- len = strlen(w->name) + sizeof("Reloading: ") + 1;
- new_title = emalloc(len);
- snprintf(new_title, len, "Reloading: %s", w->name);
- winwidget_rename(w, new_title);
- free(new_title);
-
- old_w = gib_imlib_image_get_width(w->im);
- old_h = gib_imlib_image_get_height(w->im);
-
- /*
- * If we don't free the old image before loading the new one, Imlib2's
- * caching will get in our way.
- * However, if --reload is used (force_new == 0), we want to continue if
- * the new image cannot be loaded, so we must not free the old image yet.
- */
- if (force_new)
- winwidget_free_image(w);
-
- if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) {
- if (force_new)
- eprintf("failed to reload image\n");
- else {
- im_weprintf(w, "Couldn't reload image. Is it still there?");
- winwidget_render_image(w, 0, 0);
- }
- return;
- }
-
- if (!resize && ((old_w != gib_imlib_image_get_width(tmp)) ||
- (old_h != gib_imlib_image_get_height(tmp))))
- resize = 1;
-
- if (!force_new)
- winwidget_free_image(w);
-
- w->im = tmp;
- winwidget_reset_image(w);
-
- w->mode = MODE_NORMAL;
- if ((w->im_w != gib_imlib_image_get_width(w->im))
- || (w->im_h != gib_imlib_image_get_height(w->im)))
- w->had_resize = 1;
- if (w->has_rotated) {
- Imlib_Image temp;
-
- temp = gib_imlib_create_rotated_image(w->im, 0.0);
- w->im_w = gib_imlib_image_get_width(temp);
- w->im_h = gib_imlib_image_get_height(temp);
- gib_imlib_free_image_and_decache(temp);
- } else {
- w->im_w = gib_imlib_image_get_width(w->im);
- w->im_h = gib_imlib_image_get_height(w->im);
- }
- winwidget_render_image(w, resize, 0);
-
- return;
-}
-
void slideshow_change_image(winwidget winwid, int change, int render)
{
gib_list *last = NULL;