diff options
| -rw-r--r-- | src/imlib.c | 110 | ||||
| -rw-r--r-- | src/options.c | 5 | ||||
| -rw-r--r-- | src/options.h | 1 | 
3 files changed, 108 insertions, 8 deletions
| diff --git a/src/imlib.c b/src/imlib.c index 5be0539..2d1b47a 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -61,7 +61,9 @@ int num_xinerama_screens;  int childpid = 0; +static int feh_file_is_raw(char *filename);  static char *feh_http_load_image(char *url); +static char *feh_dcraw_load_image(char *filename);  static char *feh_magick_load_image(char *filename);  #ifdef HAVE_LIBXINERAMA @@ -213,8 +215,7 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err)  int feh_load_image(Imlib_Image * im, feh_file * file)  {  	Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE; -	enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK } image_source = -		SRC_IMLIB; +	enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK, SRC_DCRAW } image_source = SRC_IMLIB;  	char *tmpname = NULL;  	char *real_filename = NULL; @@ -229,16 +230,23 @@ int feh_load_image(Imlib_Image * im, feh_file * file)  		if ((tmpname = feh_http_load_image(file->filename)) == NULL)  			err = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST;  	} +	else if (opt.dcraw_timeout >= 0 && feh_file_is_raw(file->filename)) { +		image_source = SRC_DCRAW; +		tmpname = feh_dcraw_load_image(file->filename); +		if (!tmpname) +			err = IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT; +	}  	else  		*im = imlib_load_image_with_error_return(file->filename, &err); -	if ((err == IMLIB_LOAD_ERROR_UNKNOWN) -			|| (err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT)) { +	if (opt.magick_timeout >= 0 && ( +			(err == IMLIB_LOAD_ERROR_UNKNOWN) || +			(err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT))) {  		image_source = SRC_MAGICK;  		tmpname = feh_magick_load_image(file->filename);  	} -	if ((image_source != SRC_IMLIB) && tmpname) { +	if (tmpname) {  		*im = imlib_load_image_with_error_return(tmpname, &err);  		if (!err && im) {  			real_filename = file->filename; @@ -298,6 +306,95 @@ int feh_load_image(Imlib_Image * im, feh_file * file)  	return(1);  } +static int feh_file_is_raw(char *filename) +{ +	childpid = fork(); +	if (childpid == -1) { +		perror("fork"); +		return 0; +	} + +	if (childpid == 0) { +		if (opt.quiet) { +			int devnull = open("/dev/null", O_WRONLY); +			dup2(devnull, 1); +			dup2(devnull, 2); +		} +		execlp("dcraw", "dcraw", "-i", filename, NULL); +		_exit(1); +	} else { +		int status; +		do { +			waitpid(childpid, &status, WUNTRACED); +			if (WIFEXITED(status)) { +				return !WEXITSTATUS(status); +			} +		} while (!WIFEXITED(status) && !WIFSIGNALED(status)); +	} + +	return 0; +} + +static char *feh_dcraw_load_image(char *filename) +{ +	char *basename; +	char *tmpname; +	char *sfn; +	int fd = -1; + +	basename = strrchr(filename, '/'); + +	if (basename == NULL) +		basename = filename; +	else +		basename++; + +	tmpname = feh_unique_filename("/tmp/", basename); + +	if (strlen(tmpname) > (NAME_MAX-6)) +		tmpname[NAME_MAX-7] = '\0'; + +	sfn = estrjoin("_", tmpname, "XXXXXX", NULL); +	free(tmpname); + +	fd = mkstemp(sfn); + +	if (fd == -1) { +		free(sfn); +		return NULL; +	} + +	childpid = fork(); +	if (childpid == -1) { +		weprintf("%s: Can't load with dcraw. Fork failed:", filename); +		unlink(sfn); +		free(sfn); +		close(fd); +		return NULL; +	} else if (childpid == 0) { + +		close(1); +		dup(fd); +		close(fd); + +		alarm(opt.dcraw_timeout); +		execlp("dcraw", "dcraw", "-c", "-e", filename, NULL); +		_exit(1); +	} + +	int status; +	waitpid(-1, &status, 0); +	if (WIFSIGNALED(status)) { +		unlink(sfn); +		free(sfn); +		sfn = NULL; +		if (!opt.quiet) +			weprintf("%s - Conversion took too long, skipping", filename); +	} + +	return sfn; +} +  static char *feh_magick_load_image(char *filename)  {  	char *argv_fn; @@ -309,9 +406,6 @@ static char *feh_magick_load_image(char *filename)  	int status;  	char created_tempdir = 0; -	if (opt.magick_timeout < 0) -		return NULL; -  	basename = strrchr(filename, '/');  	if (basename == NULL) diff --git a/src/options.c b/src/options.c index ab9006c..b0d67cd 100644 --- a/src/options.c +++ b/src/options.c @@ -55,6 +55,7 @@ void init_parse_options(int argc, char **argv)  	opt.display = 1;  	opt.aspect = 1;  	opt.slideshow_delay = 0.0; +	opt.dcraw_timeout = -1;  	opt.magick_timeout = -1;  	opt.thumb_w = 60;  	opt.thumb_h = 60; @@ -415,6 +416,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)  		{"insecure"      , 0, 0, 240},  		{"no-recursive"  , 0, 0, 241},  		{"cache-size"    , 1, 0, 243}, +		{"dcraw-timeout" , 1, 0, 245},  		{"version-sort"  , 0, 0, 246},  		{"offset"        , 1, 0, 247},  		{0, 0, 0, 0} @@ -783,6 +785,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)  			if (opt.cache_size > 2048)  				opt.cache_size = 2048;  			break; +		case 245: +			opt.dcraw_timeout = atoi(optarg); +			break;  		case 246:  			opt.version_sort = 1;  			break; diff --git a/src/options.h b/src/options.h index be2ca25..741b0c7 100644 --- a/src/options.h +++ b/src/options.h @@ -133,6 +133,7 @@ struct __fehoptions {  	double slideshow_delay; +	signed short dcraw_timeout;  	signed short magick_timeout;  	Imlib_Font menu_fn; | 
