Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
imageio_module.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2011 Henrik Andersson.
4 Copyright (C) 2010-2012 johannes hanika.
5 Copyright (C) 2011-2016, 2020 Tobias Ellinghaus.
6 Copyright (C) 2012-2014 Jérémy Rosen.
7 Copyright (C) 2012 Richard Wonka.
8 Copyright (C) 2013-2016 Roman Lebedev.
9 Copyright (C) 2013 Ulrich Pegelow.
10 Copyright (C) 2019 Edgardo Hoszowski.
11 Copyright (C) 2019 jakubfi.
12 Copyright (C) 2019-2021 Pascal Obry.
13 Copyright (C) 2020 a.
14 Copyright (C) 2020 Andreas Schneider.
15 Copyright (C) 2020 Chris Elston.
16 Copyright (C) 2020-2021 Diederik Ter Rahe.
17 Copyright (C) 2020 Hubert Kowalski.
18 Copyright (C) 2021 Bill Ferguson.
19 Copyright (C) 2021 Ralf Brown.
20 Copyright (C) 2022 Martin Bařinka.
21 Copyright (C) 2023 Alynx Zhou.
22
23 darktable is free software: you can redistribute it and/or modify
24 it under the terms of the GNU General Public License as published by
25 the Free Software Foundation, either version 3 of the License, or
26 (at your option) any later version.
27
28 darktable is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
32
33 You should have received a copy of the GNU General Public License
34 along with darktable. If not, see <http://www.gnu.org/licenses/>.
35*/
36
38#include "common/darktable.h"
40#include "common/imageio.h"
41#include "control/conf.h"
42#include "control/control.h"
43#include "control/signal.h"
44#include <stdlib.h>
45static gint dt_imageio_sort_modules_storage(gconstpointer a, gconstpointer b)
46{
49 return strcmp(am->name(am), bm->name(bm));
50}
51
52static gint dt_imageio_sort_modules_format(gconstpointer a, gconstpointer b)
53{
56 return strcmp(am->name(), bm->name());
57}
58
62 uint32_t *width, uint32_t *height)
63{
64 // assume no limits
65 *width = 0;
66 *height = 0;
67 return 0;
68}
71{
72 return 0;
73}
82{
83}
84
85static int dt_imageio_load_module_format(dt_imageio_module_format_t *module, const char *libname,
86 const char *module_name)
87{
88 g_strlcpy(module->plugin_name, module_name, sizeof(module->plugin_name));
89
90#define INCLUDE_API_FROM_MODULE_LOAD "imageio_load_module_format"
92
93 if(darktable.gui)
94 {
95 if(IS_NULL_PTR(module->gui_init)) goto api_h_error;
96 }
97 else
98 {
99 module->gui_init = _default_format_gui_init;
100 }
101 if(IS_NULL_PTR(module->dimension)) module->dimension = _default_format_dimension;
102 if(IS_NULL_PTR(module->flags)) module->flags = _default_format_flags;
103 if(IS_NULL_PTR(module->levels)) module->levels = _default_format_levels;
104
105 module->widget = NULL;
106 // Can by set by the module function to false if something went wrong.
107 module->ready = TRUE;
108
109 module->init(module);
110 if (!module->ready)
111 {
112 goto api_h_error;
113 }
114
115 return 0;
116}
117
118
120{
121 iio->plugins_format = NULL;
122 GList *res = NULL;
124 char moduledir[PATH_MAX] = { 0 }, plugin_name[256];
125 const gchar *d_name;
126 dt_loc_get_moduledir(moduledir, sizeof(moduledir));
127 g_strlcat(moduledir, "/plugins/imageio/format", sizeof(moduledir));
128 GDir *dir = g_dir_open(moduledir, 0, NULL);
129 if(IS_NULL_PTR(dir)) return 1;
130 const int name_offset = strlen(SHARED_MODULE_PREFIX),
131 name_end = strlen(SHARED_MODULE_PREFIX) + strlen(SHARED_MODULE_SUFFIX);
132 while((d_name = g_dir_read_name(dir)))
133 {
134 // get lib*.so
135 if(!g_str_has_prefix(d_name, SHARED_MODULE_PREFIX)) continue;
136 if(!g_str_has_suffix(d_name, SHARED_MODULE_SUFFIX)) continue;
137 g_strlcpy(plugin_name, d_name + name_offset, strlen(d_name) - name_end + 1);
138 module = (dt_imageio_module_format_t *)malloc(sizeof(dt_imageio_module_format_t));
139 gchar *libname = g_module_build_path(moduledir, (const gchar *)plugin_name);
140 if(dt_imageio_load_module_format(module, libname, plugin_name))
141 {
142 dt_free(module);
143 continue;
144 }
145 module->gui_data = NULL;
147 module->gui_init(module);
149 if(module->widget) g_object_ref_sink(module->widget);
150 dt_free(libname);
151 res = g_list_insert_sorted(res, module, dt_imageio_sort_modules_format);
152 }
153 g_dir_close(dir);
154 iio->plugins_format = res;
155 return 0;
156}
157
160 struct dt_imageio_module_format_t *format)
161{
162 return TRUE;
163}
167 uint32_t *width, uint32_t *height)
168{
169 return 0;
170}
173{
174}
175
176static int dt_imageio_load_module_storage(dt_imageio_module_storage_t *module, const char *libname,
177 const char *module_name)
178{
179 g_strlcpy(module->plugin_name, module_name, sizeof(module->plugin_name));
180
181#define INCLUDE_API_FROM_MODULE_LOAD "imageio_load_module_storage"
183
184 if(darktable.gui)
185 {
186 if(IS_NULL_PTR(module->gui_init)) goto api_h_error;
187 }
188 else
189 {
190 module->gui_init = _default_storage_nop;
191 }
192 if(IS_NULL_PTR(module->dimension)) module->dimension = _default_storage_dimension;
193 if(IS_NULL_PTR(module->recommended_dimension)) module->recommended_dimension = _default_storage_dimension;
194 if(!module->export_dispatched) module->export_dispatched = _default_storage_nop;
195
196 module->widget = NULL;
197 module->init(module);
198 return 0;
199}
200
202{
203 iio->plugins_storage = NULL;
205 char moduledir[PATH_MAX] = { 0 }, plugin_name[256];
206 const gchar *d_name;
207 dt_loc_get_moduledir(moduledir, sizeof(moduledir));
208 g_strlcat(moduledir, "/plugins/imageio/storage", sizeof(moduledir));
209 GDir *dir = g_dir_open(moduledir, 0, NULL);
210 if(IS_NULL_PTR(dir)) return 1;
211 const int name_offset = strlen(SHARED_MODULE_PREFIX),
212 name_end = strlen(SHARED_MODULE_PREFIX) + strlen(SHARED_MODULE_SUFFIX);
213 while((d_name = g_dir_read_name(dir)))
214 {
215 // get lib*.so
216 if(!g_str_has_prefix(d_name, SHARED_MODULE_PREFIX)) continue;
217 if(!g_str_has_suffix(d_name, SHARED_MODULE_SUFFIX)) continue;
218 g_strlcpy(plugin_name, d_name + name_offset, strlen(d_name) - name_end + 1);
219 module = (dt_imageio_module_storage_t *)malloc(sizeof(dt_imageio_module_storage_t));
220 gchar *libname = g_module_build_path(moduledir, (const gchar *)plugin_name);
221 if(dt_imageio_load_module_storage(module, libname, plugin_name))
222 {
223 dt_free(module);
224 continue;
225 }
226 module->gui_data = NULL;
227 module->gui_init(module);
228 if(module->widget) g_object_ref_sink(module->widget);
229 dt_free(libname);
231 }
232 g_dir_close(dir);
233 return 0;
234}
235
237{
238 iio->plugins_format = NULL;
239 iio->plugins_storage = NULL;
240
243}
244
246{
247 while(iio->plugins_format)
248 {
249 dt_imageio_module_format_t *module = (dt_imageio_module_format_t *)(iio->plugins_format->data);
250 module->gui_cleanup(module);
251 module->cleanup(module);
252 if(module->widget) g_object_unref(module->widget);
253 if(module->module) g_module_close(module->module);
254 dt_free(module);
255 iio->plugins_format = g_list_delete_link(iio->plugins_format, iio->plugins_format);
256 }
257 while(iio->plugins_storage)
258 {
259 dt_imageio_module_storage_t *module = (dt_imageio_module_storage_t *)(iio->plugins_storage->data);
260 module->gui_cleanup(module);
261 if(module->widget) g_object_unref(module->widget);
262 if(module->module) g_module_close(module->module);
263 dt_free(module);
264 iio->plugins_storage = g_list_delete_link(iio->plugins_storage, iio->plugins_storage);
265 }
266}
267
269{
271 const char *format_name = dt_conf_get_string_const("plugins/lighttable/export/format_name");
273 // if the format from the config isn't available default to jpeg, if that's not available either just use
274 // the first we have
275 if(IS_NULL_PTR(format)) format = dt_imageio_get_format_by_name("jpeg");
276 if(IS_NULL_PTR(format)) format = iio->plugins_format->data;
277 return format;
278}
279
281{
283 const char *storage_name = dt_conf_get_string_const("plugins/lighttable/export/storage_name");
285 // if the storage from the config isn't available default to disk, if that's not available either just use
286 // the first we have
287 if(IS_NULL_PTR(storage)) storage = dt_imageio_get_storage_by_name("disk");
288 if(IS_NULL_PTR(storage)) storage = iio->plugins_storage->data;
289 return storage;
290}
291
293{
294 if(IS_NULL_PTR(name)) return NULL;
296 for(GList *it = iio->plugins_format; it; it = g_list_next(it))
297 {
298 dt_imageio_module_format_t *module = (dt_imageio_module_format_t *)it->data;
299 if(!strcmp(module->plugin_name, name)) return module;
300 }
301 return NULL;
302}
303
305{
306 if(IS_NULL_PTR(name)) return NULL;
308 for(GList *it = iio->plugins_storage; it; it = g_list_next(it))
309 {
310 dt_imageio_module_storage_t *module = (dt_imageio_module_storage_t *)it->data;
311 if(!strcmp(module->plugin_name, name)) return module;
312 }
313 return NULL;
314}
315
317{
319 GList *it = g_list_nth(iio->plugins_format, index);
320 if(IS_NULL_PTR(it)) it = iio->plugins_format;
321 return (dt_imageio_module_format_t *)it->data;
322}
323
325{
327 GList *it = g_list_nth(iio->plugins_storage, index);
328 if(IS_NULL_PTR(it)) it = iio->plugins_storage;
329 return (dt_imageio_module_storage_t *)it->data;
330}
331
333{
335 return g_list_index(iio->plugins_format, format);
336}
338{
340 return g_list_index(iio->plugins_storage, storage);
341}
342
349
355
356gchar *dt_imageio_resizing_factor_get_and_parsing(double *num, double *denum)
357{
358 double _num, _denum;
359 gchar *scale_str = dt_conf_get_string("plugins/lighttable/export/resizing_factor");
360
361 char sep[4] = "";
362 snprintf( sep, 4, "%g", (double) 3/2);
363 int i = -1;
364 while(scale_str[++i])
365 {
366 if ((scale_str[i] == '.') || (scale_str[i] == ',')) scale_str[i] = sep[1];
367 }
368
369 gchar *pdiv = strchr(scale_str, '/');
370
371 if (IS_NULL_PTR(pdiv))
372 {
373 _num = atof(scale_str);
374 _denum = 1;
375 }
376 else if (pdiv-scale_str == 0)
377 {
378 _num = 1;
379 _denum = atof(pdiv + 1);
380}
381 else
382{
383 _num = atof(scale_str);
384 _denum = atof(pdiv+1);
385 }
386
387 if (_num == 0.0) _num = 1.0;
388 if (_denum == 0.0) _denum = 1.0;
389
390 *num = _num;
391 *denum = _denum;
392
393 dt_conf_set_string("plugins/lighttable/export/resizing_factor", scale_str);
394 return scale_str;
395}
396
397// clang-format off
398// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
399// vim: shiftwidth=2 expandtab tabstop=2 cindent
400// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
401// clang-format on
#define TRUE
Definition ashift_lsd.c:162
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
char * name
#define SHARED_MODULE_SUFFIX
#define SHARED_MODULE_PREFIX
gchar * dt_conf_get_string(const char *name)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
darktable_t darktable
Definition darktable.c:181
#define dt_free(ptr)
Definition darktable.h:456
#define PATH_MAX
Definition darktable.h:1062
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
void dt_loc_get_moduledir(char *moduledir, size_t bufsize)
@ IMAGEIO_RGB
Definition imageio.h:70
@ IMAGEIO_INT8
Definition imageio.h:62
static gint dt_imageio_sort_modules_format(gconstpointer a, gconstpointer b)
static void _default_format_gui_init(struct dt_imageio_module_format_t *self)
dt_imageio_module_storage_t * dt_imageio_get_storage_by_index(int index)
void dt_imageio_cleanup(dt_imageio_t *iio)
static int dt_imageio_load_modules_storage(dt_imageio_t *iio)
void dt_imageio_remove_storage(dt_imageio_module_storage_t *storage)
dt_imageio_module_storage_t * dt_imageio_get_storage()
static int _default_format_flags(dt_imageio_module_data_t *data)
int dt_imageio_get_index_of_format(dt_imageio_module_format_t *format)
static int dt_imageio_load_module_format(dt_imageio_module_format_t *module, const char *libname, const char *module_name)
static int _default_format_levels(dt_imageio_module_data_t *data)
int dt_imageio_get_index_of_storage(dt_imageio_module_storage_t *storage)
static gboolean default_supported(struct dt_imageio_module_storage_t *self, struct dt_imageio_module_format_t *format)
dt_imageio_module_format_t * dt_imageio_get_format_by_index(int index)
gchar * dt_imageio_resizing_factor_get_and_parsing(double *num, double *denum)
static int _default_storage_dimension(struct dt_imageio_module_storage_t *self, dt_imageio_module_data_t *data, uint32_t *width, uint32_t *height)
dt_imageio_module_format_t * dt_imageio_get_format()
static int dt_imageio_load_module_storage(dt_imageio_module_storage_t *module, const char *libname, const char *module_name)
void dt_imageio_init(dt_imageio_t *iio)
void dt_imageio_insert_storage(dt_imageio_module_storage_t *storage)
static void _default_storage_nop(struct dt_imageio_module_storage_t *self)
dt_imageio_module_format_t * dt_imageio_get_format_by_name(const char *name)
static gint dt_imageio_sort_modules_storage(gconstpointer a, gconstpointer b)
static int dt_imageio_load_modules_format(dt_imageio_t *iio)
dt_imageio_module_storage_t * dt_imageio_get_storage_by_name(const char *name)
static int _default_format_dimension(dt_imageio_module_format_t *module, dt_imageio_module_data_t *data, uint32_t *width, uint32_t *height)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
Definition signal.h:347
@ DT_SIGNAL_IMAGEIO_STORAGE_CHANGE
This signal is raised when a new storage module is loaded noparameters no return.
Definition signal.h:267
struct dt_imageio_t * imageio
Definition darktable.h:784
struct dt_gui_gtk_t * gui
Definition darktable.h:775
struct dt_control_signal_t * signals
Definition darktable.h:774
int32_t reset
Definition gtk.h:172
GList * plugins_storage
GList * plugins_format