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/module.h"
40#include "system/macros.h"
41#include "system/mem_alloc.h"
42#include "common/paths.h"
43#include "gui/application.h"
46#include "common/conf.h"
47#include "control/signal.h"
48#include <stdlib.h>
50static gint dt_imageio_sort_modules_storage(gconstpointer a, gconstpointer b)
51{
54 return strcmp(am->name(am), bm->name(bm));
55}
56
57static gint dt_imageio_sort_modules_format(gconstpointer a, gconstpointer b)
58{
61 return strcmp(am->name(), bm->name());
62}
63
67 uint32_t *width, uint32_t *height)
68{
69 // assume no limits
70 *width = 0;
71 *height = 0;
72 return 0;
73}
76{
77 return 0;
78}
87{
88}
89
90static int dt_imageio_load_module_format(dt_imageio_module_format_t *module, const char *libname,
91 const char *module_name)
92{
93 g_strlcpy(module->plugin_name, module_name, sizeof(module->plugin_name));
94
95#define INCLUDE_API_FROM_MODULE_LOAD "imageio_load_module_format"
97
99 {
100 if(IS_NULL_PTR(module->gui_init)) goto api_h_error;
101 }
102 else
103 {
104 module->gui_init = _default_format_gui_init;
105 }
106 if(IS_NULL_PTR(module->dimension)) module->dimension = _default_format_dimension;
107 if(IS_NULL_PTR(module->flags)) module->flags = _default_format_flags;
108 if(IS_NULL_PTR(module->levels)) module->levels = _default_format_levels;
109
110 module->widget = NULL;
111 // Can by set by the module function to false if something went wrong.
112 module->ready = TRUE;
113
114 module->init(module);
115 if (!module->ready)
116 {
117 goto api_h_error;
118 }
119
120 return 0;
121}
122
123
125{
126 iio->plugins_format = NULL;
127 GList *res = NULL;
129 char moduledir[DT_PATH_MAX] = { 0 };
130
131 gchar **plugin_names = dt_module_read_manifest("/plugins/imageio/format", moduledir);
132 if(IS_NULL_PTR(plugin_names)) return 1;
133
134 for(gchar **name = plugin_names; !IS_NULL_PTR(*name); name++)
135 {
136 const char *plugin_name = *name;
137 module = (dt_imageio_module_format_t *)malloc(sizeof(dt_imageio_module_format_t));
138 gchar *libname = g_module_build_path(moduledir, plugin_name);
139 if(dt_imageio_load_module_format(module, libname, plugin_name))
140 {
141 dt_free(libname);
142 dt_free(module);
143 continue;
144 }
145 dt_free(libname);
146 module->gui_data = NULL;
148 module->gui_init(module);
150 if(module->widget) g_object_ref_sink(module->widget);
151 res = g_list_insert_sorted(res, module, dt_imageio_sort_modules_format);
152 }
153 g_strfreev(plugin_names);
154
155 iio->plugins_format = res;
156 return 0;
157}
158
161 struct dt_imageio_module_format_t *format)
162{
163 return TRUE;
164}
168 uint32_t *width, uint32_t *height)
169{
170 return 0;
171}
174{
175}
176
177static int dt_imageio_load_module_storage(dt_imageio_module_storage_t *module, const char *libname,
178 const char *module_name)
179{
180 g_strlcpy(module->plugin_name, module_name, sizeof(module->plugin_name));
181
182#define INCLUDE_API_FROM_MODULE_LOAD "imageio_load_module_storage"
184
186 {
187 if(IS_NULL_PTR(module->gui_init)) goto api_h_error;
188 }
189 else
190 {
191 module->gui_init = _default_storage_nop;
192 }
193 if(IS_NULL_PTR(module->dimension)) module->dimension = _default_storage_dimension;
194 if(IS_NULL_PTR(module->recommended_dimension)) module->recommended_dimension = _default_storage_dimension;
195 if(!module->export_dispatched) module->export_dispatched = _default_storage_nop;
196
197 module->widget = NULL;
198 module->init(module);
199 return 0;
200}
201
203{
204 iio->plugins_storage = NULL;
206 char moduledir[DT_PATH_MAX] = { 0 };
207
208 gchar **plugin_names = dt_module_read_manifest("/plugins/imageio/storage", moduledir);
209 if(IS_NULL_PTR(plugin_names)) return 1;
210
211 for(gchar **name = plugin_names; !IS_NULL_PTR(*name); name++)
212 {
213 const char *plugin_name = *name;
214 module = (dt_imageio_module_storage_t *)malloc(sizeof(dt_imageio_module_storage_t));
215 gchar *libname = g_module_build_path(moduledir, plugin_name);
216 if(dt_imageio_load_module_storage(module, libname, plugin_name))
217 {
218 dt_free(libname);
219 dt_free(module);
220 continue;
221 }
222 dt_free(libname);
223 module->gui_data = NULL;
224 module->gui_init(module);
225 if(module->widget) g_object_ref_sink(module->widget);
227 }
228 g_strfreev(plugin_names);
229
230 return 0;
231}
232
234{
235 iio->plugins_format = NULL;
236 iio->plugins_storage = NULL;
237
240}
241
243{
244 while(iio->plugins_format)
245 {
246 dt_imageio_module_format_t *module = (dt_imageio_module_format_t *)(iio->plugins_format->data);
247 module->gui_cleanup(module);
248 module->cleanup(module);
249 if(module->widget) g_object_unref(module->widget);
250 if(module->module) g_module_close(module->module);
251 dt_free(module);
252 iio->plugins_format = g_list_delete_link(iio->plugins_format, iio->plugins_format);
253 }
254 while(iio->plugins_storage)
255 {
256 dt_imageio_module_storage_t *module = (dt_imageio_module_storage_t *)(iio->plugins_storage->data);
257 module->gui_cleanup(module);
258 if(module->widget) g_object_unref(module->widget);
259 if(module->module) g_module_close(module->module);
260 dt_free(module);
261 iio->plugins_storage = g_list_delete_link(iio->plugins_storage, iio->plugins_storage);
262 }
263}
264
266{
268 const char *format_name = dt_conf_get_string_const("plugins/lighttable/export/format_name");
270 // if the format from the config isn't available default to jpeg, if that's not available either just use
271 // the first we have
272 if(IS_NULL_PTR(format)) format = dt_imageio_get_format_by_name("jpeg");
273 if(IS_NULL_PTR(format)) format = iio->plugins_format->data;
274 return format;
275}
276
278{
280 const char *storage_name = dt_conf_get_string_const("plugins/lighttable/export/storage_name");
282 // if the storage from the config isn't available default to disk, if that's not available either just use
283 // the first we have
284 if(IS_NULL_PTR(storage)) storage = dt_imageio_get_storage_by_name("disk");
285 if(IS_NULL_PTR(storage)) storage = iio->plugins_storage->data;
286 return storage;
287}
288
290{
291 if(IS_NULL_PTR(name)) return NULL;
293 for(GList *it = iio->plugins_format; it; it = g_list_next(it))
294 {
295 dt_imageio_module_format_t *module = (dt_imageio_module_format_t *)it->data;
296 if(!strcmp(module->plugin_name, name)) return module;
297 }
298 return NULL;
299}
300
302{
303 if(IS_NULL_PTR(name)) return NULL;
305 for(GList *it = iio->plugins_storage; it; it = g_list_next(it))
306 {
307 dt_imageio_module_storage_t *module = (dt_imageio_module_storage_t *)it->data;
308 if(!strcmp(module->plugin_name, name)) return module;
309 }
310 return NULL;
311}
312
314{
316 GList *it = g_list_nth(iio->plugins_format, index);
317 if(IS_NULL_PTR(it)) it = iio->plugins_format;
318 return (dt_imageio_module_format_t *)it->data;
319}
320
322{
324 GList *it = g_list_nth(iio->plugins_storage, index);
325 if(IS_NULL_PTR(it)) it = iio->plugins_storage;
326 return (dt_imageio_module_storage_t *)it->data;
327}
328
330{
332 return g_list_index(iio->plugins_format, format);
333}
335{
337 return g_list_index(iio->plugins_storage, storage);
338}
339
346
352
353gchar *dt_imageio_resizing_factor_get_and_parsing(double *num, double *denum)
354{
355 double _num, _denum;
356 gchar *scale_str = dt_conf_get_string("plugins/lighttable/export/resizing_factor");
357
358 char sep[4] = "";
359 snprintf( sep, 4, "%g", (double) 3/2);
360 int i = -1;
361 while(scale_str[++i])
362 {
363 if ((scale_str[i] == '.') || (scale_str[i] == ',')) scale_str[i] = sep[1];
364 }
365
366 gchar *pdiv = strchr(scale_str, '/');
367
368 if (IS_NULL_PTR(pdiv))
369 {
370 _num = atof(scale_str);
371 _denum = 1;
372 }
373 else if (pdiv-scale_str == 0)
374 {
375 _num = 1;
376 _denum = atof(pdiv + 1);
377}
378 else
379{
380 _num = atof(scale_str);
381 _denum = atof(pdiv+1);
382 }
383
384 if (_num == 0.0) _num = 1.0;
385 if (_denum == 0.0) _denum = 1.0;
386
387 *num = _num;
388 *denum = _denum;
389
390 dt_conf_set_string("plugins/lighttable/export/resizing_factor", scale_str);
391 return scale_str;
392}
393
394// clang-format off
395// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
396// vim: shiftwidth=2 expandtab tabstop=2 cindent
397// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
398// clang-format on
#define TRUE
Definition ashift_lsd.c:162
gchar * dt_conf_get_string(const char *name)
Read the stored string for name as a private copy.
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
Borrow the stored string for name without copying it.
struct dt_imageio_t * dt_imageio_get_global(void)
Definition darktable.c:626
struct dt_gui_gtk_t * dt_gui_get_global(void)
Definition darktable.c:523
const int res
Definition dtpthread.h:351
@ IMAGEIO_RGB
@ IMAGEIO_INT8
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 IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:96
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
gchar ** dt_module_read_manifest(const char *subdir, char *moduledir)
Read a module directory's manifest and return the module base names it lists.
Definition module.c:56
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
Definition paths.h:57
const char * name
Definition pdf.h:90
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
Definition signal.h:386
struct dt_control_signal_t * dt_control_signal_get_global(void)
Definition darktable.c:616
@ DT_SIGNAL_IMAGEIO_STORAGE_CHANGE
This signal is raised when a new storage module is loaded noparameters no return.
Definition signal.h:270
GList * plugins_storage
GList * plugins_format
#define dt_gui_freeze_begin()
#define dt_gui_freeze_end()