added libimago
[eradicate] / libs / imago / src / ftmodule.c
diff --git a/libs/imago/src/ftmodule.c b/libs/imago/src/ftmodule.c
new file mode 100644 (file)
index 0000000..f0fc0f1
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+libimago - a multi-format image file input/output library.
+Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include "ftmodule.h"
+
+static struct list_node {
+       struct ftype_module *module;
+       struct list_node *next;
+} *modules;
+
+/* defined in modules.c which is generated by configure */
+void img_modules_init();
+
+static int done_init;
+
+int img_register_module(struct ftype_module *mod)
+{
+       struct list_node *node;
+
+       if(!(node = malloc(sizeof *node))) {
+               return -1;
+       }
+
+       node->module = mod;
+       node->next = modules;
+       modules = node;
+       return 0;
+}
+
+struct ftype_module *img_find_format_module(struct img_io *io)
+{
+       struct list_node *node;
+
+       if(!done_init) {
+               img_modules_init();
+               done_init = 1;
+       }
+
+       node = modules;
+       while(node) {
+               if(node->module->check(io) != -1) {
+                       return node->module;
+               }
+               node = node->next;
+       }
+       return 0;
+}
+
+struct ftype_module *img_guess_format(const char *fname)
+{
+       struct list_node *node;
+       char *suffix;
+       int suffix_len;
+
+       if(!done_init) {
+               img_modules_init();
+               done_init = 1;
+       }
+
+       if(!(suffix = strrchr(fname, '.'))) {
+               return 0;       /* no suffix, can't guess ... */
+       }
+       suffix_len = (int)strlen(suffix);
+
+       node = modules;
+       while(node) {
+               char *suflist = node->module->suffix;
+               char *start, *end;
+
+               while(*suflist) {
+                       if(!(start = strstr(suflist, suffix))) {
+                               break;
+                       }
+                       end = start + suffix_len;
+
+                       if(*end == ':' || *end == 0) {
+                               return node->module;    /* found it */
+                       }
+                       suflist = end;
+               }
+
+               node = node->next;
+       }
+       return 0;
+}
+
+struct ftype_module *img_get_module(int idx)
+{
+       struct list_node *node;
+
+       if(!done_init) {
+               img_modules_init();
+               done_init = 1;
+       }
+
+       node = modules;
+       while(node && idx--) {
+               node = node->next;
+       }
+       return node->module;
+}