summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/imlib.c110
-rw-r--r--src/options.c5
-rw-r--r--src/options.h1
3 files changed, 108 insertions, 8 deletions
diff --git a/src/imlib.c b/src/imlib.c
index d9c5cd0..b6041fc 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
@@ -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)
diff --git a/src/options.c b/src/options.c
index 3d11482..29ce836 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},
{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;
diff --git a/src/options.h b/src/options.h
index d4de3c5..88121e6 100644
--- a/src/options.h
+++ b/src/options.h
@@ -129,6 +129,7 @@ struct __fehoptions {
double slideshow_delay;
+ signed short dcraw_timeout;
signed short magick_timeout;
Imlib_Font menu_fn;