--- /dev/null
+/*
+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;
+}