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.
This commit is contained in:
Kim Woelders 2021-10-28 16:16:38 +02:00
parent 1cf913701c
commit ac1f75daf0
2 changed files with 170 additions and 11 deletions

View File

@ -166,7 +166,9 @@ if test "$jpeg_loader" != no ; then
else
jpeg_ok=no
fi
AM_CONDITIONAL(BUILD_JPEG_LOADER, test "$jpeg_ok" = yes)
ldr_ok=`expr "$jpeg_ok" = yes`
AM_CONDITIONAL(BUILD_JPEG_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_JPEG_LOADER, [ $ldr_ok ], [ Build JPEG loader ])
AC_MSG_CHECKING(whether to enable png support)
@ -192,7 +194,10 @@ if test "$png_loader" != no ; then
else
png_ok="no"
fi
AM_CONDITIONAL(BUILD_PNG_LOADER, test "$png_ok" = yes)
ldr_ok=`expr "$png_ok" = yes`
AM_CONDITIONAL(BUILD_PNG_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_PNG_LOADER, [ $ldr_ok ], [ Build PNG loader ])
AC_MSG_CHECKING(whether to enable webp support)
AC_ARG_WITH([webp],
@ -213,7 +218,9 @@ if test "$webp_loader" != no ; then
else
webp_ok="no"
fi
AM_CONDITIONAL(BUILD_WEBP_LOADER, test "$webp_ok" = yes)
ldr_ok=`expr "$webp_ok" = yes`
AM_CONDITIONAL(BUILD_WEBP_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_WEBP_LOADER, [ $ldr_ok ], [ Build WEBP loader ])
AC_MSG_CHECKING(whether to enable tiff support)
@ -242,7 +249,9 @@ if test "$tiff_loader" != no ; then
else
tiff_ok=no
fi
AM_CONDITIONAL(BUILD_TIFF_LOADER, test "$tiff_ok" = yes)
ldr_ok=`expr "$tiff_ok" = yes`
AM_CONDITIONAL(BUILD_TIFF_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_TIFF_LOADER, [ $ldr_ok ], [ Build TIFF loader ])
AC_MSG_CHECKING(whether to enable gif support)
@ -279,7 +288,9 @@ if test "$gif_loader" != no ; then
else
gif_ok=no
fi
AM_CONDITIONAL(BUILD_GIF_LOADER, test "$gif_ok" = yes)
ldr_ok=`expr "$gif_ok" = yes`
AM_CONDITIONAL(BUILD_GIF_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_GIF_LOADER, [ $ldr_ok ], [ Build GIF loader ])
AC_MSG_CHECKING(whether to enable zlib support)
@ -308,7 +319,9 @@ if test "$zlib_loader" != no ; then
else
zlib_ok=no
fi
AM_CONDITIONAL(BUILD_ZLIB_LOADER, test "$zlib_ok" = yes)
ldr_ok=`expr "$zlib_ok" = yes`
AM_CONDITIONAL(BUILD_ZLIB_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_ZLIB_LOADER, [ $ldr_ok ], [ Build ZLIB loader ])
AC_MSG_CHECKING(whether to enable bzip2 support)
@ -346,7 +359,9 @@ if test "$bz2_loader" != no ; then
else
bz2_ok=no
fi
AM_CONDITIONAL(BUILD_BZ2_LOADER, test "$bz2_ok" = yes)
ldr_ok=`expr "$bz2_ok" = yes`
AM_CONDITIONAL(BUILD_BZ2_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_BZ2_LOADER, [ $ldr_ok ], [ Build BZ2 loader ])
AC_MSG_CHECKING(whether to enable id3 support)
@ -375,7 +390,10 @@ if test "$id3_loader" != no ; then
else
id3_ok=no
fi
AM_CONDITIONAL(BUILD_ID3_LOADER, test "$id3_ok" = yes)
ldr_ok=`expr "$bz2_ok" = yes`
AM_CONDITIONAL(BUILD_ID3_LOADER, [ test $ldr_ok ])
AC_DEFINE_UNQUOTED(BUILD_ID3_LOADER, [ $ldr_ok ], [ Build ID3 loader ])
AM_CONDITIONAL(BUILD_TEST, false)

View File

@ -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,18 +200,56 @@ __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)
{
@ -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;
}