summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2021-10-28 16:16:38 +0200
committerKim Woelders <kim@woelders.dk>2021-11-05 17:22:01 +0100
commitac1f75daf0ff30fb04b234c506c923d1f8a59396 (patch)
tree3e588d11fcaba87d06065ea30d5e8c4cb5709dd4 /src/lib
parent1cf913701cd32ac4bc5e90332c0ecc0aab7568f5 (diff)
downloadimlib2-ac1f75daf0ff30fb04b234c506c923d1f8a59396.tar.gz
Loader loading: Avoid always loading all loaders
Introduce "known loaders" list associating the known loader modules with the usual file name extensions they handle. If file name extensions match known ones we will only load the required loader.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/loaders.c147
1 files changed, 144 insertions, 3 deletions
diff --git a/src/lib/loaders.c b/src/lib/loaders.c
index d3f2b8b..3269dc9 100644
--- a/src/lib/loaders.c
+++ b/src/lib/loaders.c
@@ -14,6 +14,96 @@
#define DP(fmt...) DC(DBG_LOAD, fmt)
static ImlibLoader *loaders = NULL;
+static char loaders_loaded = 0;
+
+typedef struct {
+ const char *dso;
+ const char *const *ext;
+} KnownLoader;
+
+static const char *const ext_argb[] = { "argb", NULL };
+static const char *const ext_bmp[] = { "bmp", NULL };
+#ifdef BUILD_BZ2_LOADER
+static const char *const ext_bz2[] = { "bz2", NULL };
+#endif
+static const char *const ext_ff[] = { "ff", NULL };
+#ifdef BUILD_GIF_LOADER
+static const char *const ext_gif[] = { "gif", NULL };
+#endif
+static const char *const ext_ico[] = { "ico", NULL };
+#ifdef BUILD_ID3_LOADER
+static const char *const ext_id3[] = { "mp3", NULL };
+#endif
+#ifdef BUILD_JPEG_LOADER
+static const char *const ext_jpeg[] = { "jpg", "jpeg", "jfif", "jfi", NULL };
+#endif
+static const char *const ext_lbm[] = { "iff", "ilbm", "lbm", NULL };
+#ifdef BUILD_PNG_LOADER
+static const char *const ext_png[] = { "png", NULL };
+#endif
+static const char *const ext_pnm[] =
+ { "pnm", "ppm", "pgm", "pbm", "pam", NULL };
+static const char *const ext_tga[] = { "tga", NULL };
+#ifdef BUILD_TIFF_LOADER
+static const char *const ext_tiff[] = { "tiff", "tif", NULL };
+#endif
+#ifdef BUILD_WEBP_LOADER
+static const char *const ext_webp[] = { "webp", NULL };
+#endif
+static const char *const ext_xbm[] = { "xbm", NULL };
+static const char *const ext_xpm[] = { "xpm", NULL };
+#ifdef BUILD_ZLIB_LOADER
+static const char *const ext_zlib[] = { "gz", NULL };
+#endif
+static const KnownLoader loaders_known[] = {
+ {"argb", ext_argb},
+ {"bmp", ext_bmp},
+#ifdef BUILD_BZ2_LOADER
+ {"bz2", ext_bz2},
+#endif
+ {"ff", ext_ff},
+#ifdef BUILD_GIF_LOADER
+ {"gif", ext_gif},
+#endif
+ {"ico", ext_ico},
+#ifdef BUILD_ID3_LOADER
+ {"id3", ext_id3},
+#endif
+#ifdef BUILD_JPEG_LOADER
+ {"jpeg", ext_jpeg},
+#endif
+ {"lbm", ext_lbm},
+#ifdef BUILD_PNG_LOADER
+ {"png", ext_png},
+#endif
+ {"pnm", ext_pnm},
+ {"tga", ext_tga},
+#ifdef BUILD_TIFF_LOADER
+ {"tiff", ext_tiff},
+#endif
+#ifdef BUILD_WEBP_LOADER
+ {"webp", ext_webp},
+#endif
+ {"xbm", ext_xbm},
+ {"xpm", ext_xpm},
+#ifdef BUILD_ZLIB_LOADER
+ {"zlib", ext_zlib},
+#endif
+};
+
+static int
+__imlib_IsLoaderLoaded(const char *file)
+{
+ ImlibLoader *l;
+
+ for (l = loaders; l; l = l->next)
+ {
+ if (strcmp(file, l->file) == 0)
+ return 1;
+ }
+
+ return 0;
+}
/* try dlopen()ing the file if we succeed finish filling out the malloced */
/* loader struct and return it */
@@ -87,6 +177,7 @@ __imlib_RemoveAllLoaders(void)
__imlib_ConsumeLoader(l);
}
loaders = NULL;
+ loaders_loaded = 0;
}
/* find all the loaders we can find and load them up to see what they can */
@@ -109,19 +200,57 @@ __imlib_LoadAllLoaders(void)
/* (or try) and if it succeeds, append to our loader list */
for (i = num - 1; i >= 0; i--)
{
- __imlib_ProduceLoader(list[i]);
+ if (!__imlib_IsLoaderLoaded(list[i]))
+ __imlib_ProduceLoader(list[i]);
free(list[i]);
}
free(list);
+
+ loaders_loaded = 1;
}
ImlibLoader **
__imlib_GetLoaderList(void)
{
+ if (!loaders_loaded)
+ __imlib_LoadAllLoaders();
return &loaders;
}
static ImlibLoader *
+__imlib_LookupKnownLoader(const char *format)
+{
+ const KnownLoader *kl;
+ ImlibLoader *l;
+ unsigned int i;
+ const char *const *exts;
+ char nbuf[4096];
+
+ kl = NULL;
+ for (i = 0; i < ARRAY_SIZE(loaders_known); i++)
+ {
+ for (exts = loaders_known[i].ext; *exts; exts++)
+ {
+ if (strcasecmp(format, *exts) != 0)
+ continue;
+ kl = &loaders_known[i];
+ goto done;
+ }
+ }
+
+ done:
+ l = NULL;
+ if (kl)
+ {
+ snprintf(nbuf, sizeof(nbuf), "%s/%s.so", __imlib_PathToLoaders(),
+ kl->dso);
+ l = __imlib_ProduceLoader(nbuf);
+ }
+ DP("%s: '%s' -> '%s': %p\n", __func__, format, kl ? kl->dso : "-", l);
+ return l;
+}
+
+static ImlibLoader *
__imlib_LookupLoadedLoader(const char *format, int for_save)
{
ImlibLoader *l;
@@ -173,11 +302,23 @@ __imlib_FindBestLoaderForFormat(const char *format, int for_save)
if (!format || format[0] == '\0')
return NULL;
- if (!loaders)
- __imlib_LoadAllLoaders();
+ if (loaders)
+ {
+ /* At least one loader loaded */
+ l = __imlib_LookupLoadedLoader(format, for_save);
+ if (l || loaders_loaded)
+ goto done;
+ }
+
+ l = __imlib_LookupKnownLoader(format);
+ if (l)
+ goto done;
+
+ __imlib_LoadAllLoaders();
l = __imlib_LookupLoadedLoader(format, for_save);
+ done:
DP("%s: fmt='%s': %s\n", __func__, format, l ? l->file : "-");
return l;
}