summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2020-03-01 05:55:25 +0100
committerKim Woelders <kim@woelders.dk>2020-03-01 06:28:28 +0100
commit07e1601cd54d9ca9ed0b8648597e8d332242d938 (patch)
treee62b527237624e917ec2c1b31e1092d6876dd736
parent6c2fe14b8247fa7df489e58d45ca374d413292dc (diff)
downloadimlib2-07e1601cd54d9ca9ed0b8648597e8d332242d938.tar.gz
Reduce number of stat() calls during load
Also skip empty files entirely.
-rw-r--r--src/lib/api.c21
-rw-r--r--src/lib/file.c2
-rw-r--r--src/lib/file.h22
-rw-r--r--src/lib/image.c28
4 files changed, 51 insertions, 22 deletions
diff --git a/src/lib/api.c b/src/lib/api.c
index b65a04d..e94bebf 100644
--- a/src/lib/api.c
+++ b/src/lib/api.c
@@ -1412,26 +1412,9 @@ imlib_load_image_with_error_return(const char *file,
CHECK_CONTEXT(ctx);
CHECK_PARAM_POINTER_RETURN("imlib_load_image_with_error_return", "file",
file, NULL);
- if (!__imlib_FileExists(file))
- {
- *error_return = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST;
- return NULL;
- }
- if (__imlib_FileIsDir(file))
- {
- *error_return = IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY;
- return NULL;
- }
- if (!__imlib_FileCanRead(file))
- {
- *error_return = IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ;
- return NULL;
- }
prev_ctxt_image = ctx->image;
- im = (Imlib_Image) __imlib_LoadImage(file,
- (ImlibProgressFunction)
- ctx->progress_func,
- ctx->progress_granularity, 1, 0, &er);
+ im = __imlib_LoadImage(file, (ImlibProgressFunction) ctx->progress_func,
+ ctx->progress_granularity, 1, 0, &er);
ctx->image = prev_ctxt_image;
if (im)
*error_return = IMLIB_LOAD_ERROR_NONE;
diff --git a/src/lib/file.c b/src/lib/file.c
index ef8eaa5..5616859 100644
--- a/src/lib/file.c
+++ b/src/lib/file.c
@@ -117,7 +117,7 @@ __imlib_FileExtension(const char *file)
return *p != '\0' ? p : NULL;
}
-static int
+int
__imlib_FileStat(const char *file, struct stat *st)
{
if ((!file) || (!*file))
diff --git a/src/lib/file.h b/src/lib/file.h
index b5e1fc6..414ef7a 100644
--- a/src/lib/file.h
+++ b/src/lib/file.h
@@ -1,6 +1,8 @@
#ifndef __FILE_H
#define __FILE_H 1
+#include <sys/stat.h>
+
#include "common.h"
int __imlib_IsRealFile(const char *s);
@@ -9,6 +11,26 @@ char *__imlib_FileRealFile(const char *file);
const char *__imlib_FileExtension(const char *file);
+int __imlib_FileStat(const char *file, struct stat *st);
+
+static inline time_t
+__imlib_StatModDate(const struct stat *st)
+{
+ return (st->st_mtime > st->st_ctime) ? st->st_mtime : st->st_ctime;
+}
+
+static inline int
+__imlib_StatIsFile(const struct stat *st)
+{
+ return S_ISREG(st->st_mode);
+}
+
+static inline int
+__imlib_StatIsDir(const struct stat *st)
+{
+ return S_ISDIR(st->st_mode);
+}
+
int __imlib_FileExists(const char *s);
int __imlib_FileIsFile(const char *s);
int __imlib_FileIsDir(const char *s);
diff --git a/src/lib/image.c b/src/lib/image.c
index 24cd1cc..2f343f9 100644
--- a/src/lib/image.c
+++ b/src/lib/image.c
@@ -526,6 +526,26 @@ __imlib_ErrorFromErrno(int err, int save)
}
}
+static int
+__imlib_FileCheck(const char *file, struct stat *st, ImlibLoadError * er)
+{
+ int err;
+
+ err = 0;
+
+ if (__imlib_FileStat(file, st))
+ err = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST;
+ else if (__imlib_StatIsDir(st))
+ err = IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY;
+ else if (st->st_size == 0)
+ err = IMLIB_LOAD_ERROR_UNKNOWN;
+
+ if (er)
+ *er = err;
+
+ return err;
+}
+
/* create a new image struct from data passed that is wize w x h then return */
/* a pointer to that image sturct */
ImlibImage *
@@ -648,6 +668,7 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
ImlibLoader *best_loader;
int loader_ret;
ImlibLdCtx ilc;
+ struct stat st;
if (!file || file[0] == '\0')
return NULL;
@@ -686,12 +707,15 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
}
}
+ if (__imlib_FileCheck(file, &st, er))
+ return NULL;
+
/* either image in cache is invalid or we dont even have it in cache */
/* so produce a new one and load an image into that */
im = __imlib_ProduceImage();
im->file = strdup(file);
- if (__imlib_IsRealFile(file))
+ if (__imlib_StatIsFile(&st))
{
im->real_file = im->file;
im->key = NULL;
@@ -711,7 +735,7 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
return NULL;
}
- im->moddate = __imlib_FileModDate(im->real_file);
+ im->moddate = __imlib_StatModDate(&st);
im->data_memory_func = imlib_context_get_image_data_memory_function();