From 5cfae636206df6f6f36d004f7dc66bcfb6d4a52c Mon Sep 17 00:00:00 2001 From: Bert Münnich Date: Tue, 10 Jun 2014 23:15:04 +0200 Subject: Create thumbnail cache dir automatically --- sxiv.1 | 16 ++------ thumbs.c | 125 ++++++++++++++++++++++++++++----------------------------------- util.c | 11 +----- 3 files changed, 61 insertions(+), 91 deletions(-) diff --git a/sxiv.1 b/sxiv.1 index e287e55..a9e83a4 100644 --- a/sxiv.1 +++ b/sxiv.1 @@ -27,9 +27,6 @@ sxiv has two modes of operation: image and thumbnail mode. The default is image mode, in which only the current image is shown. In thumbnail mode a grid of small previews is displayed, making it easy to choose an image to open. .P -sxiv can also cache its thumbnails. Please see the section THUMBNAIL CACHING -for information on how to enable this feature. -.P Please note, that the fullscreen mode requires an EWMH/NetWM compliant window manager. .SH OPTIONS @@ -371,18 +368,13 @@ keysym as listed in /usr/include/X11/keysymdef.h without the "XK_" prefix. There is also an example script installed together with sxiv as .IR PREFIX/share/sxiv/exec/key-handler . .SH THUMBNAIL CACHING -To enable thumbnail caching, please make sure to create the directory -.I $XDG_CACHE_HOME/sxiv/ -with write permissions. sxiv will then store all thumbnails inside this -directory, but it will not create this directory by itself. It rather uses the -existance of this directory as an affirmation, that the user wants thumbnails -to be cached. +sxiv stores all thumbnails under +.IR $XDG_CACHE_HOME/sxiv/ . .P Use the command line option .I \-c -to keep the cache directory clean by removing all orphaned cache files. -Additionally, run the following command afterwards inside the cache directory -to remove empty subdirectories: +to remove all orphaned cache files. Additionally, run the following command +afterwards inside the cache directory to remove empty subdirectories: .P .RS find . \-depth \-type d \-empty ! \-name '.' \-exec rmdir {} \\; diff --git a/thumbs.c b/thumbs.c index 5b1b069..519c229 100644 --- a/thumbs.c +++ b/thumbs.c @@ -36,18 +36,9 @@ void exif_auto_orientate(const fileinfo_t*); #endif +static char *cache_dir; static const int thumb_dim = THUMB_SIZE + 10; -static char *cache_dir = NULL; - -bool tns_cache_enabled(void) -{ - struct stat stats; - - return cache_dir != NULL && stat(cache_dir, &stats) == 0 && - S_ISDIR(stats.st_mode) && access(cache_dir, W_OK) == 0; -} - char* tns_cache_filepath(const char *filepath) { size_t len; @@ -107,19 +98,15 @@ void tns_cache_write(thumb_t *t, bool force) err = r_mkdir(cfile); *dirend = '/'; } - if (err == 0) { imlib_context_set_image(t->im); imlib_image_set_format("png"); imlib_save_image_with_error_return(cfile, &err); } - if (err == 0) { times.actime = fstats.st_atime; times.modtime = fstats.st_mtime; utime(cfile, ×); - } else { - warn("could not cache thumbnail: %s", t->file->name); } } free(cfile); @@ -177,7 +164,6 @@ void tns_init(tns_t *tns, int cnt, win_t *win) } else { tns->thumbs = NULL; } - tns->cap = cnt; tns->cnt = tns->first = tns->sel = 0; tns->win = win; @@ -226,7 +212,7 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file, bool force, bool silent) { int w, h; - bool use_cache, cache_hit = false; + bool cache_hit = false; float z, zw, zh; thumb_t *t; Imlib_Image im = NULL; @@ -246,64 +232,63 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file, imlib_free_image(); } - if ((use_cache = tns_cache_enabled())) { - if (!force && (im = tns_cache_load(file->path)) != NULL) - cache_hit = true; - } - - if (!cache_hit) { + if (!force && (im = tns_cache_load(file->path)) != NULL) { + cache_hit = true; + } else { #if HAVE_LIBEXIF - int pw = 0, ph = 0, x = 0, y = 0; - bool err; - ExifData *ed; - ExifEntry *entry; - ExifContent *ifd; - ExifByteOrder byte_order; - int tmpfd; - char tmppath[] = "/tmp/sxiv-XXXXXX"; - Imlib_Image tmpim; - - if ((ed = exif_data_new_from_file(file->path)) != NULL && - ed->data != NULL && ed->size > 0) - { - if ((tmpfd = mkstemp(tmppath)) >= 0) { - err = write(tmpfd, ed->data, ed->size) != ed->size; - close(tmpfd); - - if (!err && (tmpim = imlib_load_image(tmppath)) != NULL) { - byte_order = exif_data_get_byte_order(ed); - ifd = ed->ifd[EXIF_IFD_EXIF]; - entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_X_DIMENSION); - if (entry != NULL) - pw = exif_get_long(entry->data, byte_order); - entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_Y_DIMENSION); - if (entry != NULL) - ph = exif_get_long(entry->data, byte_order); - - imlib_context_set_image(tmpim); - w = imlib_image_get_width(); - h = imlib_image_get_height(); - - if (pw > w && ph > h && (pw - ph >= 0) == (w - h >= 0)) { - zw = (float) pw / (float) w; - zh = (float) ph / (float) h; - if (zw < zh) { - pw /= zh; - x = (w - pw) / 2; - w = pw; - } else if (zw > zh) { - ph /= zw; - y = (h - ph) / 2; - h = ph; + if (!force) { + int pw = 0, ph = 0, x = 0, y = 0; + bool err; + ExifData *ed; + ExifEntry *entry; + ExifContent *ifd; + ExifByteOrder byte_order; + int tmpfd; + char tmppath[] = "/tmp/sxiv-XXXXXX"; + Imlib_Image tmpim; + + if ((ed = exif_data_new_from_file(file->path)) != NULL && + ed->data != NULL && ed->size > 0) + { + if ((tmpfd = mkstemp(tmppath)) >= 0) { + err = write(tmpfd, ed->data, ed->size) != ed->size; + close(tmpfd); + + if (!err && (tmpim = imlib_load_image(tmppath)) != NULL) { + byte_order = exif_data_get_byte_order(ed); + ifd = ed->ifd[EXIF_IFD_EXIF]; + entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_X_DIMENSION); + if (entry != NULL) + pw = exif_get_long(entry->data, byte_order); + entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_Y_DIMENSION); + if (entry != NULL) + ph = exif_get_long(entry->data, byte_order); + + imlib_context_set_image(tmpim); + w = imlib_image_get_width(); + h = imlib_image_get_height(); + + if (pw > w && ph > h && (pw - ph >= 0) == (w - h >= 0)) { + zw = (float) pw / (float) w; + zh = (float) ph / (float) h; + if (zw < zh) { + pw /= zh; + x = (w - pw) / 2; + w = pw; + } else if (zw > zh) { + ph /= zw; + y = (h - ph) / 2; + h = ph; + } } + if ((im = imlib_create_cropped_image(x, y, w, h)) == NULL) + die("could not allocate memory"); + imlib_free_image_and_decache(); } - if ((im = imlib_create_cropped_image(x, y, w, h)) == NULL) - die("could not allocate memory"); - imlib_free_image_and_decache(); + unlink(tmppath); } - unlink(tmppath); + exif_data_unref(ed); } - exif_data_unref(ed); } #endif if (im == NULL && (access(file->path, R_OK) < 0 || @@ -337,7 +322,7 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file, imlib_free_image_and_decache(); - if (use_cache && !cache_hit) + if (!cache_hit) tns_cache_write(t, true); tns->dirty = true; diff --git a/util.c b/util.c index c611da4..4e48f17 100644 --- a/util.c +++ b/util.c @@ -324,14 +324,8 @@ int r_mkdir(const char *path) if (path == NULL || *path == '\0') return -1; - if (stat(path, &stats) == 0) { - if (S_ISDIR(stats.st_mode)) { - return 0; - } else { - warn("not a directory: %s", path); - return -1; - } - } + if (stat(path, &stats) == 0) + return S_ISDIR(stats.st_mode) ? 0 : -1; d = dir = (char*) s_malloc(strlen(path) + 1); strcpy(dir, path); @@ -346,7 +340,6 @@ int r_mkdir(const char *path) err = -1; } } else if (stat(dir, &stats) < 0 || !S_ISDIR(stats.st_mode)) { - warn("not a directory: %s", dir); err = -1; } if (d != NULL) -- cgit v1.2.3-54-g00ecf