summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2019-12-23 20:31:02 +0100
committerKim Woelders <kim@woelders.dk>2019-12-28 12:06:22 +0100
commit6acfd27058df7df14e57b956d149ffa23f44140d (patch)
tree48bdc86cd235db33e3a08689346d62898783c96a
parent02e85ee0695a079e738545bb8747ed863c384e6b (diff)
downloadimlib2-6acfd27058df7df14e57b956d149ffa23f44140d.tar.gz
image.c: Move loader functions to separate file
-rw-r--r--src/lib/Makefile.am1
-rw-r--r--src/lib/image.c212
-rw-r--r--src/lib/image.h5
-rw-r--r--src/lib/loaders.c220
4 files changed, 230 insertions, 208 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 2c1dded..e589ba4 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -47,6 +47,7 @@ image.c \
image.h \
image_tags.c \
line.c \
+loaders.c \
modules.c \
polygon.c \
rectangle.c \
diff --git a/src/lib/image.c b/src/lib/image.c
index a4f529a..ceaf727 100644
--- a/src/lib/image.c
+++ b/src/lib/image.c
@@ -1,7 +1,6 @@
#include "common.h"
#include <ctype.h>
-#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
@@ -16,14 +15,11 @@
#include "file.h"
#include "image.h"
-static void __imlib_LoadAllLoaders(void);
-
static ImlibImage *images = NULL;
#ifdef BUILD_X11
static ImlibImagePixmap *pixmaps = NULL;
#endif
-static ImlibLoader *loaders = NULL;
static int cache_size = 4096 * 1024;
__EXPORT__ DATA32 *
@@ -501,207 +497,6 @@ __imlib_CleanupImagePixmapCache(void)
}
#endif
-/* try dlopen()ing the file if we succeed finish filling out the malloced */
-/* loader struct and return it */
-static ImlibLoader *
-__imlib_ProduceLoader(char *file)
-{
- ImlibLoader *l;
- void (*l_formats)(ImlibLoader * l);
-
- l = malloc(sizeof(ImlibLoader));
- l->num_formats = 0;
- l->formats = NULL;
- l->handle = dlopen(file, RTLD_NOW | RTLD_LOCAL);
- if (!l->handle)
- {
- free(l);
- return NULL;
- }
- l->load = dlsym(l->handle, "load");
- l->save = dlsym(l->handle, "save");
- l_formats = dlsym(l->handle, "formats");
-
- /* each loader must provide formats() and at least load() or save() */
- if (!l_formats || (!l->load && !l->save))
- {
- dlclose(l->handle);
- free(l);
- return NULL;
- }
- l_formats(l);
- l->file = strdup(file);
- l->next = NULL;
- return l;
-}
-
-/* fre the struct for a loader and close its dlopen'd handle */
-static void
-__imlib_ConsumeLoader(ImlibLoader * l)
-{
- if (l->file)
- free(l->file);
- if (l->handle)
- dlclose(l->handle);
- if (l->formats)
- {
- int i;
-
- for (i = 0; i < l->num_formats; i++)
- free(l->formats[i]);
- free(l->formats);
- }
- free(l);
-}
-
-static void
-__imlib_RescanLoaders(void)
-{
- static time_t last_scan_time = 0;
- static time_t last_modified_system_time = 0;
- static int scanned = 0;
- time_t current_time;
- char do_reload = 0;
-
- /* dont stat the dir and rescan if we checked in the last 5 seconds */
- current_time = time(NULL);
- if ((current_time - last_scan_time) < 5)
- return;
-
- /* ok - was the system loaders dir contents modified ? */
- last_scan_time = current_time;
-
- current_time = __imlib_FileModDate(__imlib_PathToLoaders());
- if (current_time == 0)
- return; /* Loader directory not found */
- if ((current_time > last_modified_system_time) || (!scanned))
- {
- /* yup - set the "do_reload" flag */
- do_reload = 1;
- last_modified_system_time = current_time;
- }
-
- /* if we dont ned to reload the loaders - get out now */
- if (!do_reload)
- return;
-
- __imlib_RemoveAllLoaders();
- __imlib_LoadAllLoaders();
-
- scanned = 1;
-}
-
-/* remove all loaders int eh list we have cached so we can re-load them */
-void
-__imlib_RemoveAllLoaders(void)
-{
- ImlibLoader *l, *il;
-
- l = loaders;
- while (l)
- {
- il = l;
- l = l->next;
- __imlib_ConsumeLoader(il);
- }
- loaders = NULL;
-}
-
-/* find all the loaders we can find and load them up to see what they can */
-/* load / save */
-static void
-__imlib_LoadAllLoaders(void)
-{
- int i, num;
- char **list;
-
- /* list all the loaders imlib can find */
- list = __imlib_ListModules(__imlib_PathToLoaders(), &num);
- /* no loaders? well don't load anything */
- if (!list)
- return;
-
- /* go through the list of filenames for loader .so's and load them */
- /* (or try) and if it succeeds, append to our loader list */
- for (i = num - 1; i >= 0; i--)
- {
- ImlibLoader *l;
-
- l = __imlib_ProduceLoader(list[i]);
- if (l)
- {
- l->next = loaders;
- loaders = l;
- }
- if (list[i])
- free(list[i]);
- }
- free(list);
-}
-
-__EXPORT__ ImlibLoader *
-__imlib_FindBestLoaderForFormat(const char *format, int for_save)
-{
- ImlibLoader *l;
-
- if (!format || format[0] == '\0')
- return NULL;
-
- /* go through the loaders - first loader that claims to handle that */
- /* image type (extension wise) wins as a first guess to use - NOTE */
- /* this is an OPTIMISATION - it is possible the file has no extension */
- /* or has an unrecognised one but still is loadable by a loader. */
- /* if thkis initial loader failes to load the load mechanism will */
- /* systematically go from most recently used to least recently used */
- /* loader until one succeeds - or none are left and all have failed */
- /* and only if all fail does the laod fail. the lao9der that does */
- /* succeed gets it way to the head of the list so it's going */
- /* to be used first next time in this search mechanims - this */
- /* assumes you tend to laod a few image types and ones generally */
- /* of the same format */
- for (l = loaders; l; l = l->next)
- {
- int i;
-
- /* go through all the formats that loader supports */
- for (i = 0; i < l->num_formats; i++)
- {
- /* does it match ? */
- if (strcasecmp(l->formats[i], format) == 0)
- {
- /* does it provide the function we need? */
- if ((for_save && l->save) || (!for_save && l->load))
- goto done;
- }
- }
- }
-
- done:
- return l;
-}
-
-__EXPORT__ ImlibLoader *
-__imlib_FindBestLoaderForFile(const char *file, int for_save)
-{
- ImlibLoader *l;
-
- l = __imlib_FindBestLoaderForFormat(__imlib_FileExtension(file), for_save);
-
- return l;
-}
-
-static ImlibLoader *
-__imlib_FindBestLoaderForFileFormat(const char *file, char *format,
- int for_save)
-{
- /* if the format is provided ("png" "jpg" etc.) use that */
- /* otherwise us the file extension */
- if (format)
- return __imlib_FindBestLoaderForFormat(format, for_save);
- else
- return __imlib_FindBestLoaderForFile(file, for_save);
-}
-
static int
__imlib_ErrorFromErrno(int err, int save)
{
@@ -875,11 +670,12 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
}
else
{
+ ImlibLoader **loaders = __imlib_GetLoaderList();
ImlibLoader *l, *previous_l;
errno = 0;
/* run through all loaders and try load until one succeeds */
- for (l = loaders, previous_l = NULL; l; previous_l = l, l = l->next)
+ for (l = *loaders, previous_l = NULL; l; previous_l = l, l = l->next)
{
/* if its not the best loader that already failed - try load */
if (l == best_loader)
@@ -901,8 +697,8 @@ __imlib_LoadImage(const char *file, ImlibProgressFunction progress,
if (previous_l)
{
previous_l->next = l->next;
- l->next = loaders;
- loaders = l;
+ l->next = *loaders;
+ *loaders = l;
}
}
}
diff --git a/src/lib/image.h b/src/lib/image.h
index cec85e3..a6baf5a 100644
--- a/src/lib/image.h
+++ b/src/lib/image.h
@@ -104,11 +104,16 @@ struct _imlibloader {
ImlibLoader *next;
};
+void __imlib_RescanLoaders(void);
void __imlib_RemoveAllLoaders(void);
+ImlibLoader **__imlib_GetLoaderList(void);
ImlibLoader *__imlib_FindBestLoaderForFile(const char *file,
int for_save);
ImlibLoader *__imlib_FindBestLoaderForFormat(const char *format,
int for_save);
+ImlibLoader *__imlib_FindBestLoaderForFileFormat(const char *file,
+ char *format,
+ int for_save);
ImlibImage *__imlib_CreateImage(int w, int h, DATA32 * data);
ImlibImage *__imlib_LoadImage(const char *file,
diff --git a/src/lib/loaders.c b/src/lib/loaders.c
new file mode 100644
index 0000000..cd9461f
--- /dev/null
+++ b/src/lib/loaders.c
@@ -0,0 +1,220 @@
+#include "common.h"
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "file.h"
+#include "image.h"
+
+static void __imlib_LoadAllLoaders(void);
+
+static ImlibLoader *loaders = NULL;
+
+ImlibLoader **
+__imlib_GetLoaderList(void)
+{
+ return &loaders;
+}
+
+/* try dlopen()ing the file if we succeed finish filling out the malloced */
+/* loader struct and return it */
+static ImlibLoader *
+__imlib_ProduceLoader(char *file)
+{
+ ImlibLoader *l;
+ void (*l_formats)(ImlibLoader * l);
+
+ l = malloc(sizeof(ImlibLoader));
+ l->num_formats = 0;
+ l->formats = NULL;
+ l->handle = dlopen(file, RTLD_NOW | RTLD_LOCAL);
+ if (!l->handle)
+ {
+ free(l);
+ return NULL;
+ }
+ l->load = dlsym(l->handle, "load");
+ l->save = dlsym(l->handle, "save");
+ l_formats = dlsym(l->handle, "formats");
+
+ /* each loader must provide formats() and at least load() or save() */
+ if (!l_formats || (!l->load && !l->save))
+ {
+ dlclose(l->handle);
+ free(l);
+ return NULL;
+ }
+ l_formats(l);
+ l->file = strdup(file);
+ l->next = NULL;
+ return l;
+}
+
+/* fre the struct for a loader and close its dlopen'd handle */
+static void
+__imlib_ConsumeLoader(ImlibLoader * l)
+{
+ if (l->file)
+ free(l->file);
+ if (l->handle)
+ dlclose(l->handle);
+ if (l->formats)
+ {
+ int i;
+
+ for (i = 0; i < l->num_formats; i++)
+ free(l->formats[i]);
+ free(l->formats);
+ }
+ free(l);
+}
+
+void
+__imlib_RescanLoaders(void)
+{
+ static time_t last_scan_time = 0;
+ static time_t last_modified_system_time = 0;
+ static int scanned = 0;
+ time_t current_time;
+ char do_reload = 0;
+
+ /* dont stat the dir and rescan if we checked in the last 5 seconds */
+ current_time = time(NULL);
+ if ((current_time - last_scan_time) < 5)
+ return;
+
+ /* ok - was the system loaders dir contents modified ? */
+ last_scan_time = current_time;
+
+ current_time = __imlib_FileModDate(__imlib_PathToLoaders());
+ if (current_time == 0)
+ return; /* Loader directory not found */
+ if ((current_time > last_modified_system_time) || (!scanned))
+ {
+ /* yup - set the "do_reload" flag */
+ do_reload = 1;
+ last_modified_system_time = current_time;
+ }
+
+ /* if we dont ned to reload the loaders - get out now */
+ if (!do_reload)
+ return;
+
+ __imlib_RemoveAllLoaders();
+ __imlib_LoadAllLoaders();
+
+ scanned = 1;
+}
+
+/* remove all loaders int eh list we have cached so we can re-load them */
+void
+__imlib_RemoveAllLoaders(void)
+{
+ ImlibLoader *l, *il;
+
+ l = loaders;
+ while (l)
+ {
+ il = l;
+ l = l->next;
+ __imlib_ConsumeLoader(il);
+ }
+ loaders = NULL;
+}
+
+/* find all the loaders we can find and load them up to see what they can */
+/* load / save */
+static void
+__imlib_LoadAllLoaders(void)
+{
+ int i, num;
+ char **list;
+
+ /* list all the loaders imlib can find */
+ list = __imlib_ListModules(__imlib_PathToLoaders(), &num);
+ /* no loaders? well don't load anything */
+ if (!list)
+ return;
+
+ /* go through the list of filenames for loader .so's and load them */
+ /* (or try) and if it succeeds, append to our loader list */
+ for (i = num - 1; i >= 0; i--)
+ {
+ ImlibLoader *l;
+
+ l = __imlib_ProduceLoader(list[i]);
+ if (l)
+ {
+ l->next = loaders;
+ loaders = l;
+ }
+ if (list[i])
+ free(list[i]);
+ }
+ free(list);
+}
+
+__EXPORT__ ImlibLoader *
+__imlib_FindBestLoaderForFormat(const char *format, int for_save)
+{
+ ImlibLoader *l;
+
+ if (!format || format[0] == '\0')
+ return NULL;
+
+ /* go through the loaders - first loader that claims to handle that */
+ /* image type (extension wise) wins as a first guess to use - NOTE */
+ /* this is an OPTIMISATION - it is possible the file has no extension */
+ /* or has an unrecognised one but still is loadable by a loader. */
+ /* if thkis initial loader failes to load the load mechanism will */
+ /* systematically go from most recently used to least recently used */
+ /* loader until one succeeds - or none are left and all have failed */
+ /* and only if all fail does the laod fail. the lao9der that does */
+ /* succeed gets it way to the head of the list so it's going */
+ /* to be used first next time in this search mechanims - this */
+ /* assumes you tend to laod a few image types and ones generally */
+ /* of the same format */
+ for (l = loaders; l; l = l->next)
+ {
+ int i;
+
+ /* go through all the formats that loader supports */
+ for (i = 0; i < l->num_formats; i++)
+ {
+ /* does it match ? */
+ if (strcasecmp(l->formats[i], format) == 0)
+ {
+ /* does it provide the function we need? */
+ if ((for_save && l->save) || (!for_save && l->load))
+ goto done;
+ }
+ }
+ }
+
+ done:
+ return l;
+}
+
+__EXPORT__ ImlibLoader *
+__imlib_FindBestLoaderForFile(const char *file, int for_save)
+{
+ ImlibLoader *l;
+
+ l = __imlib_FindBestLoaderForFormat(__imlib_FileExtension(file), for_save);
+
+ return l;
+}
+
+ImlibLoader *
+__imlib_FindBestLoaderForFileFormat(const char *file, char *format,
+ int for_save)
+{
+ /* if the format is provided ("png" "jpg" etc.) use that */
+ /* otherwise us the file extension */
+ if (format)
+ return __imlib_FindBestLoaderForFormat(format, for_save);
+ else
+ return __imlib_FindBestLoaderForFile(file, for_save);
+}