Commit 05e745a5 authored by ulteq's avatar ulteq
Browse files

Utilize dcraw to preview RAW files

Uses the camera-generated thumbnail to display RAW images that could otherwise not be loaded.
parent b7867141
Loading
Loading
Loading
Loading
+102 −8
Original line number Diff line number Diff line
@@ -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
@@ -216,8 +218,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;

@@ -232,16 +233,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;
@@ -301,6 +309,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;
@@ -310,9 +407,6 @@ static char *feh_magick_load_image(char *filename)
	int fd = -1, devnull = -1;
	int status;

	if (opt.magick_timeout < 0)
		return NULL;

	basename = strrchr(filename, '/');

	if (basename == NULL)
+5 −0
Original line number Diff line number Diff line
@@ -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},
		{0, 0, 0, 0}
	};
@@ -781,6 +783,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;
+1 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ struct __fehoptions {

	double slideshow_delay;

	signed short dcraw_timeout;
	signed short magick_timeout;

	Imlib_Font menu_fn;