1 /* This file is part of GEGL
2  *
3  * GEGL is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 3 of the License, or (at your option) any later version.
7  *
8  * GEGL is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
15  *
16  * Copyright 2006 Øyvind Kolås <pippin@gimp.org>
17  * Copyright 2016 Martin Blanchard <tchaik@gmx.com>
18  *  */
19 
20 #include "config.h"
21 #include <glib.h>
22 
23 #include "gegl-operation-handlers.h"
24 #include "gegl-operation-handlers-private.h"
25 
26 static GHashTable *load_handlers = NULL;
27 static GHashTable *save_handlers = NULL;
28 
29 static gboolean
gegl_operation_handlers_register_util(GHashTable ** handlers,const gchar * content_type,const gchar * handler)30 gegl_operation_handlers_register_util (GHashTable **handlers,
31                                        const gchar *content_type,
32                                        const gchar *handler)
33 {
34   gchar *type = NULL;
35 
36   if (g_str_has_prefix (content_type, "."))
37     type = g_utf8_casefold (content_type, -1);
38   else if (g_str_has_prefix (content_type, "image/"))
39     type = g_strdup (content_type);
40   else
41     return FALSE;
42 
43   if (*handlers == NULL)
44     *handlers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
45 
46   g_hash_table_insert (*handlers, type, g_strdup (handler));
47 
48   return TRUE;
49 }
50 
51 gboolean
gegl_operation_handlers_register_loader(const gchar * content_type,const gchar * handler)52 gegl_operation_handlers_register_loader (const gchar *content_type,
53                                          const gchar *handler)
54 {
55   return gegl_operation_handlers_register_util (&load_handlers,
56                                                 content_type,
57                                                 handler);
58 }
59 
60 gboolean
gegl_operation_handlers_register_saver(const gchar * content_type,const gchar * handler)61 gegl_operation_handlers_register_saver (const gchar *content_type,
62                                         const gchar *handler)
63 {
64   return gegl_operation_handlers_register_util (&save_handlers,
65                                                 content_type,
66                                                 handler);
67 }
68 
69 static const gchar *
gegl_operation_handlers_get_util(GHashTable * handlers,const gchar * content_type,const gchar * handler_type,const gchar * fallback)70 gegl_operation_handlers_get_util (GHashTable *handlers,
71                                   const gchar *content_type,
72                                   const gchar *handler_type,
73                                   const gchar *fallback)
74 {
75   const gchar *handler = NULL;
76   gchar *type = NULL;
77 
78   if (handlers == NULL)
79     return NULL;
80 
81   if (g_str_has_prefix (content_type, "."))
82     type = g_utf8_casefold (content_type, -1);
83   else if (g_str_has_prefix (content_type, "image/"))
84     type = g_strdup (content_type);
85   else
86     return NULL;
87 
88   handler = g_hash_table_lookup (handlers, type);
89 
90   g_free (type);
91 
92   if (handler != NULL)
93     return handler;
94 
95   g_warning ("No %s for content type \"%s\", falling back to \"%s\"",
96              handler_type, content_type, fallback);
97 
98   return fallback;
99 }
100 
101 const gchar *
gegl_operation_handlers_get_loader(const gchar * content_type)102 gegl_operation_handlers_get_loader (const gchar *content_type)
103 {
104   return gegl_operation_handlers_get_util (load_handlers,
105                                            content_type,
106                                            "loader",
107                                            "gegl:magick-load");
108 }
109 
110 const gchar *
gegl_operation_handlers_get_saver(const gchar * content_type)111 gegl_operation_handlers_get_saver (const gchar *content_type)
112 {
113   return gegl_operation_handlers_get_util (save_handlers,
114                                            content_type,
115                                            "saver",
116                                            "gegl:png-save");
117 }
118 
119 void
gegl_operation_handlers_cleanup(void)120 gegl_operation_handlers_cleanup (void)
121 {
122   if (load_handlers != NULL)
123     {
124       g_hash_table_destroy (load_handlers);
125       load_handlers = NULL;
126     }
127 
128   if (save_handlers != NULL)
129     {
130       g_hash_table_destroy (save_handlers);
131       save_handlers = NULL;
132     }
133 }
134