diff options
author | Kim Woelders <kim@woelders.dk> | 2019-12-23 20:31:02 +0100 |
---|---|---|
committer | Kim Woelders <kim@woelders.dk> | 2019-12-28 12:06:22 +0100 |
commit | 6acfd27058df7df14e57b956d149ffa23f44140d (patch) | |
tree | 48bdc86cd235db33e3a08689346d62898783c96a | |
parent | 02e85ee0695a079e738545bb8747ed863c384e6b (diff) | |
download | imlib2-6acfd27058df7df14e57b956d149ffa23f44140d.tar.gz |
image.c: Move loader functions to separate file
-rw-r--r-- | src/lib/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/image.c | 212 | ||||
-rw-r--r-- | src/lib/image.h | 5 | ||||
-rw-r--r-- | src/lib/loaders.c | 220 |
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); +} |