| @@ -36,18 +36,9 @@ |
| 36 | 36 | | void exif_auto_orientate(const fileinfo_t*); |
| 37 | 37 | | #endif |
| 38 | 38 | | |
| 39 | + | static char *cache_dir; |
| 39 | 40 | | static const int thumb_dim = THUMB_SIZE + 10; |
| 40 | 41 | | |
| 41 | | − | static char *cache_dir = NULL; |
| 42 | | − | |
| 43 | | − | bool tns_cache_enabled(void) |
| 44 | | − | { |
| 45 | | − | struct stat stats; |
| 46 | | − | |
| 47 | | − | return cache_dir != NULL && stat(cache_dir, &stats) == 0 && |
| 48 | | − | S_ISDIR(stats.st_mode) && access(cache_dir, W_OK) == 0; |
| 49 | | − | } |
| 50 | | − | |
| 51 | 42 | | char* tns_cache_filepath(const char *filepath) |
| 52 | 43 | | { |
| 53 | 44 | | size_t len; |
| @@ -107,19 +98,15 @@ void tns_cache_write(thumb_t *t, bool force) |
| 107 | 98 | | err = r_mkdir(cfile); |
| 108 | 99 | | *dirend = '/'; |
| 109 | 100 | | } |
| 110 | | − | |
| 111 | 101 | | if (err == 0) { |
| 112 | 102 | | imlib_context_set_image(t->im); |
| 113 | 103 | | imlib_image_set_format("png"); |
| 114 | 104 | | imlib_save_image_with_error_return(cfile, &err); |
| 115 | 105 | | } |
| 116 | | − | |
| 117 | 106 | | if (err == 0) { |
| 118 | 107 | | times.actime = fstats.st_atime; |
| 119 | 108 | | times.modtime = fstats.st_mtime; |
| 120 | 109 | | utime(cfile, ×); |
| 121 | | − | } else { |
| 122 | | − | warn("could not cache thumbnail: %s", t->file->name); |
| 123 | 110 | | } |
| 124 | 111 | | } |
| 125 | 112 | | free(cfile); |
| @@ -177,7 +164,6 @@ void tns_init(tns_t *tns, int cnt, win_t *win) |
| 177 | 164 | | } else { |
| 178 | 165 | | tns->thumbs = NULL; |
| 179 | 166 | | } |
| 180 | | − | |
| 181 | 167 | | tns->cap = cnt; |
| 182 | 168 | | tns->cnt = tns->first = tns->sel = 0; |
| 183 | 169 | | tns->win = win; |
| @@ -226,7 +212,7 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file, |
| 226 | 212 | | bool force, bool silent) |
| 227 | 213 | | { |
| 228 | 214 | | int w, h; |
| 229 | | − | bool use_cache, cache_hit = false; |
| 215 | + | bool cache_hit = false; |
| 230 | 216 | | float z, zw, zh; |
| 231 | 217 | | thumb_t *t; |
| 232 | 218 | | Imlib_Image im = NULL; |
| @@ -246,64 +232,63 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file, |
| 246 | 232 | | imlib_free_image(); |
| 247 | 233 | | } |
| 248 | 234 | | |
| 249 | | − | if ((use_cache = tns_cache_enabled())) { |
| 250 | | − | if (!force && (im = tns_cache_load(file->path)) != NULL) |
| 251 | | − | cache_hit = true; |
| 252 | | − | } |
| 253 | | − | |
| 254 | | − | if (!cache_hit) { |
| 235 | + | if (!force && (im = tns_cache_load(file->path)) != NULL) { |
| 236 | + | cache_hit = true; |
| 237 | + | } else { |
| 255 | 238 | | #if HAVE_LIBEXIF |
| 256 | | − | int pw = 0, ph = 0, x = 0, y = 0; |
| 257 | | − | bool err; |
| 258 | | − | ExifData *ed; |
| 259 | | − | ExifEntry *entry; |
| 260 | | − | ExifContent *ifd; |
| 261 | | − | ExifByteOrder byte_order; |
| 262 | | − | int tmpfd; |
| 263 | | − | char tmppath[] = "/tmp/sxiv-XXXXXX"; |
| 264 | | − | Imlib_Image tmpim; |
| 265 | | − | |
| 266 | | − | if ((ed = exif_data_new_from_file(file->path)) != NULL && |
| 267 | | − | ed->data != NULL && ed->size > 0) |
| 268 | | − | { |
| 269 | | − | if ((tmpfd = mkstemp(tmppath)) >= 0) { |
| 270 | | − | err = write(tmpfd, ed->data, ed->size) != ed->size; |
| 271 | | − | close(tmpfd); |
| 272 | | − | |
| 273 | | − | if (!err && (tmpim = imlib_load_image(tmppath)) != NULL) { |
| 274 | | − | byte_order = exif_data_get_byte_order(ed); |
| 275 | | − | ifd = ed->ifd[EXIF_IFD_EXIF]; |
| 276 | | − | entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_X_DIMENSION); |
| 277 | | − | if (entry != NULL) |
| 278 | | − | pw = exif_get_long(entry->data, byte_order); |
| 279 | | − | entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_Y_DIMENSION); |
| 280 | | − | if (entry != NULL) |
| 281 | | − | ph = exif_get_long(entry->data, byte_order); |
| 282 | | − | |
| 283 | | − | imlib_context_set_image(tmpim); |
| 284 | | − | w = imlib_image_get_width(); |
| 285 | | − | h = imlib_image_get_height(); |
| 286 | | − | |
| 287 | | − | if (pw > w && ph > h && (pw - ph >= 0) == (w - h >= 0)) { |
| 288 | | − | zw = (float) pw / (float) w; |
| 289 | | − | zh = (float) ph / (float) h; |
| 290 | | − | if (zw < zh) { |
| 291 | | − | pw /= zh; |
| 292 | | − | x = (w - pw) / 2; |
| 293 | | − | w = pw; |
| 294 | | − | } else if (zw > zh) { |
| 295 | | − | ph /= zw; |
| 296 | | − | y = (h - ph) / 2; |
| 297 | | − | h = ph; |
| 239 | + | if (!force) { |
| 240 | + | int pw = 0, ph = 0, x = 0, y = 0; |
| 241 | + | bool err; |
| 242 | + | ExifData *ed; |
| 243 | + | ExifEntry *entry; |
| 244 | + | ExifContent *ifd; |
| 245 | + | ExifByteOrder byte_order; |
| 246 | + | int tmpfd; |
| 247 | + | char tmppath[] = "/tmp/sxiv-XXXXXX"; |
| 248 | + | Imlib_Image tmpim; |
| 249 | + | |
| 250 | + | if ((ed = exif_data_new_from_file(file->path)) != NULL && |
| 251 | + | ed->data != NULL && ed->size > 0) |
| 252 | + | { |
| 253 | + | if ((tmpfd = mkstemp(tmppath)) >= 0) { |
| 254 | + | err = write(tmpfd, ed->data, ed->size) != ed->size; |
| 255 | + | close(tmpfd); |
| 256 | + | |
| 257 | + | if (!err && (tmpim = imlib_load_image(tmppath)) != NULL) { |
| 258 | + | byte_order = exif_data_get_byte_order(ed); |
| 259 | + | ifd = ed->ifd[EXIF_IFD_EXIF]; |
| 260 | + | entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_X_DIMENSION); |
| 261 | + | if (entry != NULL) |
| 262 | + | pw = exif_get_long(entry->data, byte_order); |
| 263 | + | entry = exif_content_get_entry(ifd, EXIF_TAG_PIXEL_Y_DIMENSION); |
| 264 | + | if (entry != NULL) |
| 265 | + | ph = exif_get_long(entry->data, byte_order); |
| 266 | + | |
| 267 | + | imlib_context_set_image(tmpim); |
| 268 | + | w = imlib_image_get_width(); |
| 269 | + | h = imlib_image_get_height(); |
| 270 | + | |
| 271 | + | if (pw > w && ph > h && (pw - ph >= 0) == (w - h >= 0)) { |
| 272 | + | zw = (float) pw / (float) w; |
| 273 | + | zh = (float) ph / (float) h; |
| 274 | + | if (zw < zh) { |
| 275 | + | pw /= zh; |
| 276 | + | x = (w - pw) / 2; |
| 277 | + | w = pw; |
| 278 | + | } else if (zw > zh) { |
| 279 | + | ph /= zw; |
| 280 | + | y = (h - ph) / 2; |
| 281 | + | h = ph; |
| 282 | + | } |
| 298 | 283 | | } |
| 284 | + | if ((im = imlib_create_cropped_image(x, y, w, h)) == NULL) |
| 285 | + | die("could not allocate memory"); |
| 286 | + | imlib_free_image_and_decache(); |
| 299 | 287 | | } |
| 300 | | − | if ((im = imlib_create_cropped_image(x, y, w, h)) == NULL) |
| 301 | | − | die("could not allocate memory"); |
| 302 | | − | imlib_free_image_and_decache(); |
| 288 | + | unlink(tmppath); |
| 303 | 289 | | } |
| 304 | | − | unlink(tmppath); |
| 290 | + | exif_data_unref(ed); |
| 305 | 291 | | } |
| 306 | | − | exif_data_unref(ed); |
| 307 | 292 | | } |
| 308 | 293 | | #endif |
| 309 | 294 | | 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, |
| 337 | 322 | | |
| 338 | 323 | | imlib_free_image_and_decache(); |
| 339 | 324 | | |
| 340 | | − | if (use_cache && !cache_hit) |
| 325 | + | if (!cache_hit) |
| 341 | 326 | | tns_cache_write(t, true); |
| 342 | 327 | | |
| 343 | 328 | | tns->dirty = true; |