Write thumbnail cache files on exit
This commit is contained in:
		
							parent
							
								
									83bdf67d51
								
							
						
					
					
						commit
						c21a3e3f28
					
				
							
								
								
									
										71
									
								
								thumbs.c
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								thumbs.c
									
									
									
									
									
								
							| @ -18,6 +18,7 @@ | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/time.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| @ -292,6 +293,9 @@ int tns_translate(tns_t *tns, int x, int y) { | ||||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* thumbnail caching */ | ||||
| 
 | ||||
| int tns_cache_enabled() { | ||||
| 	int len, ret = 0; | ||||
| 	char *cpath, *homedir; | ||||
| @ -309,5 +313,70 @@ int tns_cache_enabled() { | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void tns_cache_write(thumb_t *t, Bool force) { | ||||
| char* tns_cache_filename(const char *filename) { | ||||
| 	size_t len; | ||||
| 	int i; | ||||
| 	char *cfile, *abspath, *homedir; | ||||
| 
 | ||||
| 	if (!filename) | ||||
| 		return NULL; | ||||
| 	if (!(homedir = getenv("HOME"))) | ||||
| 		return NULL; | ||||
| 	 | ||||
| 	if (*filename != '/') { | ||||
| 		if (!(abspath = absolute_path(filename))) | ||||
| 			return NULL; | ||||
| 	} else { | ||||
| 		abspath = (char*) s_malloc(strlen(filename) + 1); | ||||
| 		strcpy(abspath, filename); | ||||
| 	} | ||||
| 
 | ||||
| 	len = strlen(abspath); | ||||
| 	for (i = 1; i < len; ++i) { | ||||
| 		if (abspath[i] == '/') | ||||
| 			abspath[i] = '%'; | ||||
| 	} | ||||
| 
 | ||||
| 	len += strlen(homedir) + 15; | ||||
| 	cfile = (char*) s_malloc(len); | ||||
| 	snprintf(cfile, len, "%s/.sxiv/%s.png", homedir, abspath + 1); | ||||
| 	 | ||||
| 	free(abspath); | ||||
| 
 | ||||
| 	return cfile; | ||||
| } | ||||
| 
 | ||||
| void tns_cache_write(thumb_t *t, Bool force) { | ||||
| 	char *cfile; | ||||
| 	struct stat cstats, fstats; | ||||
| 	struct timeval times[2]; | ||||
| 	Imlib_Load_Error err; | ||||
| 
 | ||||
| 	if (!t || !t->im || !t->filename) | ||||
| 		return; | ||||
| 
 | ||||
| 	if ((cfile = tns_cache_filename(t->filename))) { | ||||
| 		if (stat(t->filename, &fstats)) | ||||
| 			goto end; | ||||
| 
 | ||||
| 		if (force || stat(cfile, &cstats) || | ||||
| 		    cstats.st_mtim.tv_sec != fstats.st_mtim.tv_sec || | ||||
| 		    cstats.st_mtim.tv_nsec != fstats.st_mtim.tv_nsec) | ||||
| 		{ | ||||
| 			imlib_context_set_image(t->im); | ||||
| 			imlib_image_set_format("png"); | ||||
| 			imlib_save_image_with_error_return(cfile, &err); | ||||
| 
 | ||||
| 			if (err) { | ||||
| 				warn("could not cache thumbnail:", t->filename); | ||||
| 			} else { | ||||
| 				TIMESPEC_TO_TIMEVAL(×[0], &fstats.st_atim); | ||||
| 				TIMESPEC_TO_TIMEVAL(×[1], &fstats.st_mtim); | ||||
| 				utimes(cfile, times); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| end: | ||||
| 	free(cfile); | ||||
| } | ||||
|  | ||||
							
								
								
									
										80
									
								
								util.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								util.c
									
									
									
									
									
								
							| @ -18,11 +18,13 @@ | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| 
 | ||||
| #include "options.h" | ||||
| #include "util.h" | ||||
| 
 | ||||
| #define FNAME_LEN 512 | ||||
| #define FNAME_LEN 1024 | ||||
| 
 | ||||
| void cleanup(); | ||||
| 
 | ||||
| @ -78,6 +80,82 @@ void size_readable(float *size, const char **unit) { | ||||
| 	*unit = units[MIN(i, LEN(units) - 1)]; | ||||
| } | ||||
| 
 | ||||
| char* absolute_path(const char *filename) { | ||||
| 	size_t len; | ||||
| 	char *path = NULL; | ||||
| 	const char *basename; | ||||
| 	char *dirname = NULL; | ||||
| 	char *cwd = NULL; | ||||
| 	char *twd = NULL; | ||||
| 	char *dir; | ||||
| 	char *s; | ||||
| 
 | ||||
| 	if (!filename || *filename == '\0' || *filename == '/') | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	len = FNAME_LEN; | ||||
| 	cwd = (char*) s_malloc(len); | ||||
| 	while (!(s = getcwd(cwd, len)) && errno == ERANGE) { | ||||
| 		len *= 2; | ||||
| 		cwd = (char*) s_realloc(cwd, len); | ||||
| 	} | ||||
| 	if (!s) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	s = strrchr(filename, '/'); | ||||
| 	if (s) { | ||||
| 		len = s - filename; | ||||
| 		dirname = (char*) s_malloc(len + 1); | ||||
| 		strncpy(dirname, filename, len); | ||||
| 		dirname[len] = '\0'; | ||||
| 		basename = s + 1; | ||||
| 
 | ||||
| 		if (chdir(cwd)) | ||||
| 			/* we're not able to come back afterwards */ | ||||
| 			goto error; | ||||
| 		if (chdir(dirname)) | ||||
| 			goto error; | ||||
| 
 | ||||
| 		len = FNAME_LEN; | ||||
| 		twd = (char*) s_malloc(len); | ||||
| 		while (!(s = getcwd(twd, len)) && errno == ERANGE) { | ||||
| 			len *= 2; | ||||
| 			twd = (char*) s_realloc(twd, len); | ||||
| 		} | ||||
| 		if (chdir(cwd)) | ||||
| 			die("could not revert to working directory"); | ||||
| 		if (!s) | ||||
| 			goto error; | ||||
| 		dir = twd; | ||||
| 	} else { | ||||
| 		/* only a single filename given */ | ||||
| 		basename = filename; | ||||
| 		dir = cwd; | ||||
| 	} | ||||
| 
 | ||||
| 	len = strlen(dir) + strlen(basename) + 2; | ||||
| 	path = (char*) s_malloc(len); | ||||
| 	snprintf(path, len, "%s/%s", dir, basename); | ||||
| 
 | ||||
| goto end; | ||||
| 
 | ||||
| error: | ||||
| 	if (path) { | ||||
| 		free(path); | ||||
| 		path = NULL; | ||||
| 	} | ||||
| 
 | ||||
| end: | ||||
| 	if (dirname) | ||||
| 		free(dirname); | ||||
| 	if (cwd) | ||||
| 		free(cwd); | ||||
| 	if (twd) | ||||
| 		free(twd); | ||||
| 
 | ||||
| 	return path; | ||||
| } | ||||
| 
 | ||||
| char* readline(FILE *stream) { | ||||
| 	size_t len; | ||||
| 	char *buf, *s, *end; | ||||
|  | ||||
							
								
								
									
										7
									
								
								util.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								util.h
									
									
									
									
									
								
							| @ -30,6 +30,11 @@ | ||||
| #define TV_TO_DOUBLE(x) ((double) ((x).tv_sec) + 0.000001 * \ | ||||
|                          (double) ((x).tv_usec)) | ||||
| 
 | ||||
| #define TIMESPEC_TO_TIMEVAL(tv, ts) {      \ | ||||
| 		(tv)->tv_sec = (ts)->tv_sec;           \ | ||||
| 		(tv)->tv_usec = (ts)->tv_nsec / 1000;  \ | ||||
| } | ||||
| 
 | ||||
| void* s_malloc(size_t); | ||||
| void* s_realloc(void*, size_t); | ||||
| 
 | ||||
| @ -38,6 +43,8 @@ void die(const char*, ...); | ||||
| 
 | ||||
| void size_readable(float*, const char**); | ||||
| 
 | ||||
| char* absolute_path(const char*); | ||||
| 
 | ||||
| char* readline(FILE*); | ||||
| 
 | ||||
| #endif /* UTIL_H */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Bert
						Bert