Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
useless.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010 Bruce Guenter.
4 Copyright (C) 2010-2012 johannes hanika.
5 Copyright (C) 2011 Henrik Andersson.
6 Copyright (C) 2011 Jérémy Rosen.
7 Copyright (C) 2011-2014, 2016, 2019 Tobias Ellinghaus.
8 Copyright (C) 2012 Richard Wonka.
9 Copyright (C) 2014 Ulrich Pegelow.
10 Copyright (C) 2015 Pedro Côrte-Real.
11 Copyright (C) 2015-2016 Roman Lebedev.
12 Copyright (C) 2018-2021 Pascal Obry.
13 Copyright (C) 2020 Aldric Renaudin.
14 Copyright (C) 2020, 2022 Diederik Ter Rahe.
15 Copyright (C) 2020-2021 Hubert Kowalski.
16 Copyright (C) 2020-2021 Ralf Brown.
17 Copyright (C) 2021 luzpaz.
18 Copyright (C) 2022 Hanno Schwalm.
19 Copyright (C) 2022 Martin Bařinka.
20 Copyright (C) 2022 Philipp Lutz.
21 Copyright (C) 2022 Sebatian Glasl.
22 Copyright (C) 2025-2026 Aurélien PIERRE.
23
24 darktable is free software: you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation, either version 3 of the License, or
27 (at your option) any later version.
28
29 darktable is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with darktable. If not, see <http://www.gnu.org/licenses/>.
36*/
37#ifdef HAVE_CONFIG_H
38#include "common/darktable.h"
39#include "config.h"
40#endif
41// our includes go first:
42#include "bauhaus/bauhaus.h"
43#include "develop/imageop.h"
44#include "develop/imageop_gui.h"
46#include "gui/gtk.h"
47#include "iop/iop_api.h"
48
49#include <gtk/gtk.h>
50#include <stdlib.h>
51
52// This is an example implementation of an image operation module that does nothing useful.
53// It demonstrates how the different functions work together. To build your own module,
54// take all of the functions that are mandatory, stripping them of comments.
55// Then add only the optional functions that are required to implement the functionality
56// you need. Don't copy default implementations (hint: if you don't need to change or add
57// anything, you probably don't need the copy). Make sure you choose descriptive names
58// for your fields and variables. The ones given here are just examples; rename them.
59//
60// To have your module compile and appear in darkroom, add it to CMakeLists.txt, with
61// add_iop(useless "useless.c")
62// and to iop_order.c, in the initialisation of legacy_order & v30_order with:
63// { {XX.0f }, "useless", 0},
64
65// This is the version of the module's parameters,
66// and includes version information about compile-time dt.
67// The first released version should be 1.
69
70// TODO: some build system to support dt-less compilation and translation!
71
72// Enums used in params_t can have $DESCRIPTIONs that will be used to
73// automatically populate a combobox with dt_bauhaus_combobox_from_params.
74// They are also used in the history changes tooltip.
75// Combobox options will be presented in the same order as defined here.
76// These numbers must not be changed when a new version is introduced.
78{
79 DT_USELESS_NONE = 0, // $DESCRIPTION: "no"
80 DT_USELESS_FIRST = 1, // $DESCRIPTION: "first option"
81 DT_USELESS_SECOND = 2, // $DESCRIPTION: "second one"
83
85{
86 // The parameters defined here fully record the state of the module and are stored
87 // (as a serialized binary blob) into the db.
88 // Make sure everything is in here does not depend on temporary memory (pointers etc).
89 // This struct defines the layout of self->params and self->default_params.
90 // You should keep changes to this struct to a minimum.
91 // If you have to change this struct, it will break
92 // user data bases, and you have to increment the version
93 // of DT_MODULE_INTROSPECTION(VERSION) above and provide a legacy_params upgrade path!
94 //
95 // Tags in the comments get picked up by the introspection framework and are
96 // used in gui_init to set range and labels (for widgets and history)
97 // and value checks before commit_params.
98 // If no explicit init() is specified, the default implementation uses $DEFAULT tags
99 // to initialise self->default_params, which is then used in gui_init to set widget defaults.
100 //
101 // These field names are just examples; chose meaningful ones! For performance reasons, align
102 // to 4 byte boundaries (use gboolean, not bool).
103 int checker_scale; // $MIN: 0 $MAX: 10 $DEFAULT: 1 $DESCRIPTION: "size"
104 float factor; // $MIN: -5.0 $MAX: 5.0 $DEFAULT: 0
105 gboolean check; // $DESCRIPTION: "checkbox option"
106 dt_iop_useless_type_t method; // $DEFAULT: DT_USELESS_SECOND $DESCRIPTION: "parameter choices"
108
110{
111 // Whatever you need to make your gui happy and provide access to widgets between gui_init, gui_update etc.
112 // Stored in self->gui_data while in darkroom.
113 // To permanently store per-user gui configuration settings, you could use dt_conf_set/_get.
114 GtkWidget *scale, *factor, *check, *method, *extra; // this is needed by gui_update
116
118{
119 // This is optionally stored in self->global_data
120 // and can be used to alloc globally needed stuff
121 // which is needed in gui mode and during processing.
122
123 // We don't need it for this example (as for most dt plugins).
125
126// this returns a translatable name
127const char *name()
128{
129 // make sure you put all your translatable strings into _() !
130 return _("silly example");
131}
132
133// some additional flags (self explanatory i think):
134int flags()
135{
137 // optionally add IOP_FLAGS_ALLOW_TILING and implement tiling_callback
138}
139
140// where does it appear in the gui?
142{
143 return IOP_GROUP_BASIC | IOP_GROUP_TECHNICAL;
144}
145
147{
148 return IOP_CS_RGB;
149}
150
151// Whenever new fields are added to (or removed from) dt_iop_..._params_t or when their meaning
152// changes, a translation from the old to the new version must be added here.
153// A verbatim copy of the old struct definition should be copied into the routine with a _v?_t ending.
154// Since this will get very little future testing (because few developers still have very
155// old versions lying around) existing code should be changed as little as possible, if at all.
156//
157// Upgrading from an older version than the previous one should always go through all in between versions
158// (unless there was a bug) so that the end result will always be the same.
159//
160// Be careful with changes to structs that are included in _params_t
161//
162// Individually copy each existing field that is still in the new version. This is robust even if reordered.
163// If only new fields were added at the end, one call can be used:
164// memcpy(n, o, sizeof *o);
165//
166// Hardcode the default values for new fields that were added, rather than referring to default_params;
167// in future, the field may not exist anymore or the default may change. The best default for a new version
168// to replicate a previous version might not be the optimal default for a fresh image.
169//
170// FIXME: the calling logic needs to be improved to call upgrades from consecutive version in sequence.
171int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version,
172 void *new_params, const int new_version)
173{
174 typedef dt_iop_useless_params_t dt_iop_useless_params_v3_t; // always create copy of current so code below doesn't need to be touched
175
176 typedef struct dt_iop_useless_params_v2_t
177 {
178 int checker_scale;
179 float factor;
180 } dt_iop_useless_params_v2_t;
181
182 if(old_version == 2 && new_version == 3)
183 {
184 dt_iop_useless_params_v2_t *o = (dt_iop_useless_params_v2_t *)old_params;
185 dt_iop_useless_params_v3_t *n = (dt_iop_useless_params_v3_t *)new_params;
186
187 memcpy(n, o, sizeof *o);
188 n->check = FALSE;
189 n->method = DT_USELESS_SECOND;
190 return 0;
191 }
192
193 typedef struct dt_iop_useless_params_v1_t
194 {
195 int checker_scale;
196 } dt_iop_useless_params_v1_t;
197
198 if(old_version == 1 && new_version == 2)
199 {
200 dt_iop_useless_params_v1_t *o = (dt_iop_useless_params_v1_t *)old_params;
201 dt_iop_useless_params_v2_t *n = (dt_iop_useless_params_v2_t *)new_params;
202
203 n->checker_scale = o->checker_scale;
204 n->factor = 0.0;
205 return 0;
206 }
207 return 1;
208}
209
210static const int mask_id = 1; // key "0" is reserved for the pipe
211static const char *mask_name = "useless checkerboard";
212
214{
216 piece->data_size = sizeof(dt_iop_useless_params_t);
217}
219{
220 dt_free_align(piece->data);
221 piece->data = NULL;
222}
223
225{
226 memcpy(piece->data, p1, self->params_size);
227
228 // there is no real need for this, but if the number of masks can be changed by the user this is the way to go.
229 // otherwise we can have old stale masks floating around
230 g_hash_table_remove_all(self->raster_mask.source.masks);
231 g_hash_table_insert(self->raster_mask.source.masks, GINT_TO_POINTER(mask_id), g_strdup(mask_name));
232}
233
234#if 0
238void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
239{
240 const dt_iop_roi_t *const roi_in = &piece->roi_in;
241 const dt_iop_roi_t *const roi_out = &piece->roi_out;
242 tiling->factor = 2.0f; // input buffer + output buffer; increase if additional memory allocated
243 tiling->factor_cl = 2.0f; // same, but for OpenCL code path running on GPU
244 tiling->maxbuf = 1.0f; // largest buffer needed regardless of how tiling splits up the processing
245 tiling->maxbuf_cl = 1.0f; // same, but for running on GPU
246 tiling->overhead = 0; // number of bytes of fixed overhead
247 tiling->overlap = 0; // how many pixels do we need to access from the neighboring tile?
248 tiling->xalign = 1;
249 tiling->yalign = 1;
250}
251#endif
252
254// void modify_roi_out(struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, dt_iop_roi_t
255// *roi_out, const dt_iop_roi_t *roi_in);
256// void modify_roi_in(struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t
257// *roi_out, dt_iop_roi_t *roi_in);
258
259#if 0
262 float *points, size_t points_count)
263{
265
266 const float adjx = 0.0 * d->factor;
267 const float adjy = 0.0;
268
269 // nothing to be done if parameters are set to neutral values (no pixel shifts)
270 if (adjx == 0.0 && adjy == 0.0) return 1;
271
272 // apply the coordinate adjustment to each provided point
273 for(size_t i = 0; i < points_count * 2; i += 2)
274 {
275 points[i] -= adjx;
276 points[i + 1] -= adjy;
277 }
278
279 return 1; // return 1 on success, 0 if one or more points could not be transformed
280}
281#endif
282
283#if 0
286 float *points, size_t points_count)
287{
289
290 const float adjx = 0.0 * d->factor;
291 const float adjy = 0.0;
292
293 // nothing to be done if parameters are set to neutral values (no pixel shifts)
294 if (adjx == 0.0 && adjy == 0.0) return 1;
295
296 // apply the inverse coordinate adjustment to each provided point
297 for(size_t i = 0; i < points_count * 2; i += 2)
298 {
299 points[i] += adjx;
300 points[i + 1] += adjy;
301 }
302
303 return 1; // return 1 on success, 0 if one or more points could not be back-transformed
304}
305#endif
306
308// void distort_mask(struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, const float *const in,
309// float *const out, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out);
310
319int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
320{
321 const dt_iop_roi_t *const roi_in = &piece->roi_in;
322 const dt_iop_roi_t *const roi_out = &piece->roi_out;
323 // this is called for preview and full pipe separately, each with its own pixelpipe piece.
324 // get our data struct:
326 // the total scale is composed of scale before input to the pipeline (iscale),
327 // and the scale of the roi.
328 const float scale = dt_dev_get_module_scale(pipe, roi_in);
329 // how many colors in our buffer?
330 const size_t ch = piece->dsc_in.channels;
331
332 // most modules only support a single type of input data, so we can check whether that format has been supplied
333 // and simply pass along the data if not (setting a trouble flag to inform the user)
335
336 // we create a raster mask as an example
337 float *mask = NULL;
339 {
340 // Attempt to allocate all of the buffers we need. For this example, we need one buffer that is equal in
341 // dimensions to the output buffer, has one color channel, and has been zero'd. (See common/imagebuf.h for
342 // more details on all of the options.)
343 if (dt_iop_alloc_image_buffers(module, roi_in, roi_out,
344 1/*ch per pixel*/ | DT_IMGSZ_OUTPUT | DT_IMGSZ_FULL | DT_IMGSZ_CLEARBUF, &mask,
345 0 /* end of list of buffers to allocate */))
346 {
347 // Uh oh, we didn't have enough memory! If multiple buffers were requested, any that had already
348 // been allocated have been freed, and the module's trouble flag has been set. We can simply pass
349 // through the input image and return now, since there isn't anything else we need to clean up at
350 // this point.
351 dt_iop_copy_image_roi(ovoid, ivoid, ch, roi_in, roi_out, TRUE);
352 return 1;
353 }
354 }
355
356// iterate over all output pixels (same coordinates as input)
357#ifdef _OPENMP
358// optional: parallelize it!
359#pragma omp parallel for default(firstprivate)
360#endif
361 for(int j = 0; j < roi_out->height; j++)
362 {
363 float *in = ((float *)ivoid)
364 + (size_t)ch * roi_in->width
365 * j; // make sure to address input, output and temp buffers with size_t as we want to also
366 float *out = ((float *)ovoid) + (size_t)ch * roi_out->width * j; // correctly handle huge images
367 float *out_mask = mask ? &(mask[(size_t)roi_out->width * j]) : NULL;
368 for(int i = 0; i < roi_out->width; i++)
369 {
370 // calculate world space coordinates:
371 int wi = (roi_in->x + i) * scale, wj = (roi_in->y + j) * scale;
372 if((wi / d->checker_scale + wj / d->checker_scale) & 1)
373 {
374 for_each_channel(c, aligned(in,out)) // vectorize if possible
375 out[c] = in[c] * (1.0 - d->factor); // does this for c=0..2 or c=0..3, whichever is faster
376 if(!IS_NULL_PTR(out_mask)) out_mask[i] = 1.0;
377 }
378 else
379 {
380 copy_pixel(out, in);
381 }
382 in += ch;
383 out += ch;
384 }
385 }
386
387 // now that the mask is generated we can publish it
388 if(!IS_NULL_PTR(mask))
389 {
390 const size_t mask_size = sizeof(float) * (size_t)roi_out->width * roi_out->height;
391 const uint64_t mask_hash = dt_dev_pixelpipe_raster_mask_hash(piece, mask_id);
392 dt_pixel_cache_entry_t *mask_entry = NULL;
393 void *cache_data = NULL;
394 const int created = dt_dev_pixelpipe_cache_get(
395 darktable.pixelpipe_cache, mask_hash, mask_size, "useless raster mask",
396 pipe->type, TRUE, &cache_data, &mask_entry);
397
398 if(IS_NULL_PTR(cache_data) || IS_NULL_PTR(mask_entry))
399 {
400 if(created && !IS_NULL_PTR(mask_entry))
402 darktable.pixelpipe_cache, FALSE, mask_entry);
403 if(!IS_NULL_PTR(mask_entry))
404 {
406 darktable.pixelpipe_cache, FALSE, mask_entry);
407 if(created)
409 darktable.pixelpipe_cache, TRUE, mask_entry);
410 }
412 return 1;
413 }
414
415 if(created)
416 {
417 memcpy(cache_data, mask, mask_size);
419 darktable.pixelpipe_cache, FALSE, mask_entry);
420 }
421 dt_dev_pixelpipe_t *mutable_pipe = (dt_dev_pixelpipe_t *)pipe;
422 g_array_append_val(mutable_pipe->raster_mask_hashes, mask_hash);
424 }
425}
426
429{
430 // Allocates memory for a module instance and fills default_params.
431 // If this callback is not provided, the standard implementation in
432 // dt_iop_default_init is used, which looks at the $DEFAULT introspection tags
433 // in the comments of the params_t struct definition.
434 // An explicit implementation of init is only required if not all fields are
435 // fully supported by dt_iop_default_init, for example arrays with non-identical values.
436 // In that case, dt_iop_default_init can be called first followed by additional initialisation.
437 // The values in params will not be used and default_params can be overwritten by
438 // reload_params on a per-image basis.
439 dt_iop_default_init(module);
440
441 // Any non-default settings; for example disabling the on/off switch:
442 module->hide_enable_button = 1;
443 // To make this work correctly, you also need to hide the widgets, otherwise moving one
444 // would enable the module anyway. The standard way is to set up a gtk_stack and show
445 // the page that only has a label with an explanatory text when the module can't be used.
446}
447
449{
450 module->data = malloc(sizeof(dt_iop_useless_global_data_t));
451}
452
454{
455 // Releases any memory allocated in init(module)
456 // Implement this function explicitly if the module allocates additional memory besides (default_)params.
457 // this is rare.
458 dt_free(module->params);
459 dt_free(module->default_params);
460}
461
463{
464 dt_free(module->data);
465}
466
469{
470 // this is important to avoid cycles!
471 if(darktable.gui->reset) return;
472
475
476 float extra = dt_bauhaus_slider_get(w);
477
478 // Setting a widget value will trigger a callback that will update params.
479 // If this is not desirable (because it might result in a cycle) then use
480 // ++darktable.gui->reset;
481 dt_bauhaus_slider_set(g->factor, p->factor + extra);
482 // and reverse with --darktable.gui->reset;
483
484 // If any params updated directly, not via a callback, then
485 // let core know of the changes
487}
488
490void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
491{
492 // If defined, this gets called when any of the introspection based widgets
493 // (created with dt_bauhaus_..._from_params) are changed.
494 // The updated value from the widget is already set in params.
495 // any additional side-effects can be achieved here.
498
499 // Test which widget was changed.
500 // If allowing IS_NULL_PTR(w), this can be called from gui_update, so that
501 // gui configuration adjustments only need to be dealt with once, here.
502 if(IS_NULL_PTR(w) || w == g->method)
503 {
504 gtk_widget_set_visible(g->check, p->method == DT_USELESS_SECOND);
505 }
506
507 // Widget configurations that don't depend any any current params values should
508 // go in reload_defaults (if they depend on the image) or gui_init.
509}
510
512{
515
516 // This automatically gets called when any of the color pickers set up with
517 // dt_color_picker_new in gui_init is used. If there is more than one,
518 // check which one is active first.
519 if(picker == g->factor)
520 {
521 p->factor = self->picked_color[1];
522 }
523
526}
527
530{
531 // This gets called when switching to darkroom, with each image change or when
532 // a different history item is selected.
533 // Here, all the widgets need to be set to the current values in param.
534 //
535 // Note, this moves data from params -> gui. All fields at same time.
536 // The opposite direction, gui -> params happens one field at a time, for example
537 // when the user manipulates a slider. It is handled by gui_changed (and the
538 // automatic callback) for introspection based widgets or by the explicit callback
539 // set up manually (see example of extra_callback above).
542
543 dt_bauhaus_slider_set(g->scale, p->checker_scale);
544
545 // For introspection based widgets (dt_bauhaus_slider_from_params) do not use
546 // any transformations here (for example *100 for percentages) because that will
547 // break enforcement of $MIN/$MAX.
548 // Use dt_bauhaus_slider_set_factor/offset in gui_init instead.
549 dt_bauhaus_slider_set(g->factor, p->factor);
550
551 // dt_bauhaus_toggle_from_params creates a standard gtk_toggle_button.
552 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->check), p->check);
553
554 // Use set_from_value to correctly handle out of order values.
555 dt_bauhaus_combobox_set_from_value(g->method, p->method);
556
557 // Any configuration changes to the gui that depend on field values should be done here,
558 // or can be done in gui_changed which can then be called from here with IS_NULL_PTR(widget).
559 gui_changed(self, NULL, NULL);
560}
561
565{
566 // This only has to be provided if module settings or default_params need to depend on
567 // image type (raw?) or exif data.
568 // Make sure to always reset to the default for non-special cases, otherwise the override
569 // will stick when switching to another image.
571
572 // As an example, switch off for non-raw images. The enable button was already hidden in init().
573 if(!dt_image_is_raw(&module->dev->image_storage))
574 {
575 module->default_enabled = 0;
576 }
577 else
578 {
579 module->default_enabled = 1;
580 d->checker_scale = 3; // something dependent on exif, for example.
581 }
582
583 // If we are in darkroom, gui_init will already have been called and has initialised
584 // module->gui_data and widgets.
585 // So if default values have been changed, it may then be necessary to also change the
586 // default values in widgets. Resetting the individual widgets will then have the same
587 // effect as resetting the whole module at once.
589 if(!IS_NULL_PTR(g))
590 {
591 dt_bauhaus_slider_set_default(g->scale, d->checker_scale);
592 }
593}
594
600gboolean force_enable(struct dt_iop_module_t *self, const gboolean current_state)
601{
602 // This needs to be enabled for raw images, disabled for other images.
603 // There is no messing around.
604
605 const int is_raw = dt_image_is_raw(&self->dev->image_storage);
606 gboolean enable = current_state;
607
608 if(is_raw && (!self->enabled))
609 {
610 enable = TRUE;
611 }
612 else if(!is_raw && (self->enabled))
613 {
614 enable = FALSE;
615 }
616 return enable;
617}
618
619
621{
622 // Allocates memory for the module's user interface in the darkroom and
623 // sets up the widgets in it.
624 //
625 // self->widget needs to be set to the top level widget.
626 // This can be a (vertical) box, a grid or even a notebook. Modules that are
627 // disabled for certain types of images (for example non-raw) may use a stack
628 // where one of the pages contains just a label explaining why it is disabled.
629 //
630 // Widgets that are directly linked to a field in params_t may be set up using the
631 // dt_bauhaus_..._from_params family. They take a string with the field
632 // name in the params_t struct definition. The $MIN, $MAX and $DEFAULT tags will be
633 // used to set up the widget (slider) ranges and default values and the $DESCRIPTION
634 // is used as the widget label.
635 //
636 // The _from_params calls also set up an automatic callback that updates the field in params
637 // whenever the widget is changed. In addition, gui_changed is called, if it exists,
638 // so that any other required changes, to dependent fields or to gui widgets, can be made.
639 //
640 // Whenever self->params changes (switching images or history) the widget values have to
641 // be updated in gui_update.
642 //
643 // Do not set the value of widgets or configure them depending on field values here;
644 // this should be done in gui_update (or gui_changed or individual widget callbacks)
645 //
646 // If any default values for (slider) widgets or options (in comboboxes) depend on the
647 // type of image, then the widgets have to be updated in reload_params.
649
650 // If the first widget is created using a _from_params call, self->widget does not have to
651 // be explicitly initialised, as a new vertical box will be created automatically.
652 self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
653
654 // Linking a slider to an integer will make it take only whole numbers (step=1).
655 // The new slider is added to self->widget
656 g->scale = dt_bauhaus_slider_from_params(self, "checker_scale");
657
658 // If the field name should be used as label too, it does not need a $DESCRIPTION;
659 // mark it for translation here using N_()
660 //
661 // A colorpicker can be attached to a slider, as here, or put standalone in a box.
662 // When a color is picked, color_picker_apply is called with either the slider or the
663 // button that triggered it.
665 dt_bauhaus_slider_from_params(self, N_("factor")));
666 // The initial slider range can be reduced from the introspection $MIN - $MAX
667 dt_bauhaus_slider_set_soft_range(g->factor, 0.5f, 1.5f);
668 // The default step is range/100, but can be changed here
669 dt_bauhaus_slider_set_step(g->factor, .1);
671 // Additional parameters determine how the value will be shown.
672 dt_bauhaus_slider_set_format(g->factor, "%");
673 // For a percentage, use factor 100.
674 dt_bauhaus_slider_set_factor(g->factor, -100.0f);
675 dt_bauhaus_slider_set_offset(g->factor, 100.0f);
676 // Tooltips explain the otherwise compact interface
677 gtk_widget_set_tooltip_text(g->factor, _("adjust factor"));
678
679 // A combobox linked to struct field will be filled with the values and $DESCRIPTIONs
680 // in the struct definition, in the same order. The automatic callback will put the
681 // enum value, not the position within the combobox list, in the field.
682 g->method = dt_bauhaus_combobox_from_params(self, "method");
683
684 g->check = dt_bauhaus_toggle_from_params(self, "check");
685
686 // Any widgets that are _not_ directly linked to a field need to have a custom callback
687 // function set up to respond to the "value-changed" signal.
688 g->extra = dt_bauhaus_slider_new_with_range(darktable.bauhaus, DT_GUI_MODULE(self), -0.5, 0.5, 0, 0, 2);
689 dt_bauhaus_widget_set_label(g->extra, N_("extra"));
690 gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->extra), TRUE, TRUE, 0);
691 g_signal_connect(G_OBJECT(g->extra), "value-changed", G_CALLBACK(extra_callback), self);
692}
693
695{
696 // This only needs to be provided if gui_init allocates any memory or resources besides
697 // self->widget and gui_data_t. The default function (if an explicit one isn't provided here)
698 // takes care of gui_data_t (and gtk destroys the widget anyway). If you override the default,
699 // you have to do whatever you have to do, and also call IOP_GUI_FREE to clean up gui_data_t.
700
702}
703
705// void gui_post_expose(dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx,
706// int32_t pointery);
707// int mouse_moved(dt_iop_module_t *self, double x, double y, double pressure, int which);
708// int button_pressed(dt_iop_module_t *self, double x, double y, double pressure, int which, int type,
709// uint32_t state);
710// int button_released(struct dt_iop_module_t *self, double x, double y, int which, uint32_t state);
711// int scrolled(dt_iop_module_t *self, double x, double y, int up, uint32_t state);
712
713// clang-format off
714// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
715// vim: shiftwidth=2 expandtab tabstop=2 cindent
716// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
717// clang-format on
int distort_transform(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, float *const restrict points, size_t points_count)
Definition ashift.c:991
int distort_backtransform(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, float *points, size_t points_count)
Definition ashift.c:1022
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
Definition bauhaus.c:1647
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
Definition bauhaus.c:3534
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
Definition bauhaus.c:1640
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:3483
gboolean dt_bauhaus_combobox_set_from_value(GtkWidget *widget, int value)
Definition bauhaus.c:2330
void dt_bauhaus_slider_set_offset(GtkWidget *widget, float offset)
Definition bauhaus.c:3618
void dt_bauhaus_slider_set_step(GtkWidget *widget, float val)
Definition bauhaus.c:3548
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3506
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1653
GtkWidget * dt_bauhaus_slider_new_with_range(dt_bauhaus_t *bh, dt_gui_module_t *self, float min, float max, float step, float defval, int digits)
Definition bauhaus.c:1780
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
Definition bauhaus.c:3598
void dt_bauhaus_slider_set_factor(GtkWidget *widget, float factor)
Definition bauhaus.c:3611
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_RGB
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
@ DT_COLOR_PICKER_AREA
const dt_colormatrix_t dt_aligned_pixel_t out
gboolean dt_image_is_raw(const dt_image_t *img)
void dt_control_queue_redraw_widget(GtkWidget *widget)
threadsafe request of redraw of specific widget. Use this function if you need to redraw a specific w...
Definition control.c:906
darktable_t darktable
Definition darktable.c:181
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
static void copy_pixel(float *const __restrict__ out, const float *const __restrict__ in)
Definition darktable.h:688
#define for_each_channel(_var,...)
Definition darktable.h:662
#define dt_free(ptr)
Definition darktable.h:456
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:453
#define __DT_CLONE_TARGETS__
Definition darktable.h:367
#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
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:41
#define DT_GUI_BOX_SPACING
Definition gtk.h:109
#define DT_GUI_MODULE(x)
static gboolean enable(dt_image_t *image)
int dt_iop_alloc_image_buffers(struct dt_iop_module_t *const module, const struct dt_iop_roi_t *const roi_in, const struct dt_iop_roi_t *const roi_out,...)
Definition imagebuf.c:31
void dt_iop_copy_image_roi(float *const __restrict__ out, const float *const __restrict__ in, const size_t ch, const dt_iop_roi_t *const __restrict__ roi_in, const dt_iop_roi_t *const __restrict__ roi_out, const int zero_pad)
Definition imagebuf.c:159
#define DT_IMGSZ_CLEARBUF
Definition imagebuf.h:58
#define DT_IMGSZ_OUTPUT
Definition imagebuf.h:54
#define DT_IMGSZ_FULL
Definition imagebuf.h:61
gboolean dt_iop_is_raster_mask_used(dt_iop_module_t *module, int id)
Definition imageop.c:3067
void dt_iop_default_init(dt_iop_module_t *module)
Definition imageop.c:316
float dt_dev_get_module_scale(const dt_dev_pixelpipe_t *const pipe, const dt_iop_roi_t *const roi_in)
Definition imageop.c:131
#define IOP_GUI_FREE
Definition imageop.h:602
@ IOP_FLAGS_INCLUDE_IN_STYLES
Definition imageop.h:166
@ IOP_FLAGS_SUPPORTS_BLENDING
Definition imageop.h:167
@ IOP_GROUP_TECHNICAL
Definition imageop.h:143
#define IOP_GUI_ALLOC(module)
Definition imageop.h:599
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
Definition imageop_gui.c:77
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
void *const ovoid
float *const restrict const size_t const size_t ch
const float factor
Definition pdf.h:90
uint64_t dt_dev_pixelpipe_raster_mask_hash(const dt_dev_pixelpipe_iop_t *piece, const int raster_mask_id)
Definition pixelpipe.c:53
void dt_dev_pixelpipe_cache_ref_count_entry(dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Increase/Decrease the reference count on the cache line as to prevent LRU item removal....
int dt_dev_pixelpipe_cache_get(dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const size_t size, const char *name, const int id, const gboolean alloc, void **data, dt_pixel_cache_entry_t **entry)
Get a cache line from the cache.
int dt_dev_pixelpipe_cache_remove(dt_dev_pixelpipe_cache_t *cache, const gboolean force, dt_pixel_cache_entry_t *cache_entry)
Arbitrarily remove the cache entry matching hash. Entries having a reference count > 0 (inter-thread ...
void dt_dev_pixelpipe_cache_wrlock_entry(dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the write lock on the entry.
struct _GtkWidget GtkWidget
Definition splash.h:29
unsigned __int64 uint64_t
Definition strptime.c:75
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
Definition darktable.h:790
struct dt_gui_gtk_t * gui
Definition darktable.h:775
struct dt_bauhaus_t * bauhaus
Definition darktable.h:778
struct dt_develop_t * develop
Definition darktable.h:770
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_dev_pixelpipe_type_t type
gboolean store_all_raster_masks
GArray * raster_mask_hashes
dt_image_t image_storage
Definition develop.h:259
int32_t reset
Definition gtk.h:172
unsigned int channels
Definition format.h:54
dt_iop_global_data_t * data
Definition imageop.h:233
dt_iop_params_t * default_params
Definition imageop.h:307
GHashTable * masks
Definition imageop.h:328
struct dt_iop_module_t::@31 raster_mask
GtkWidget * widget
Definition imageop.h:337
struct dt_develop_t * dev
Definition imageop.h:296
struct dt_iop_module_t::@31::@32 source
dt_iop_gui_data_t * gui_data
Definition imageop.h:311
gboolean enabled
Definition imageop.h:298
int32_t params_size
Definition imageop.h:309
dt_aligned_pixel_t picked_color
Definition imageop.h:272
dt_iop_params_t * params
Definition imageop.h:307
Region of interest passed through the pixelpipe.
Definition imageop.h:72
dt_iop_useless_type_t method
Definition useless.c:106
void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
Definition atrous.c:645
void init(dt_iop_module_t *module)
Definition useless.c:428
int default_group()
Definition useless.c:141
__DT_CLONE_TARGETS__ int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
Definition useless.c:319
void reload_defaults(dt_iop_module_t *module)
Definition useless.c:564
static const int mask_id
Definition useless.c:210
dt_iop_useless_type_t
Definition useless.c:78
@ DT_USELESS_NONE
Definition useless.c:79
@ DT_USELESS_FIRST
Definition useless.c:80
@ DT_USELESS_SECOND
Definition useless.c:81
void gui_update(dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
Definition useless.c:529
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition useless.c:213
void cleanup(dt_iop_module_t *module)
Definition useless.c:453
const char * name()
Definition useless.c:127
void gui_init(dt_iop_module_t *self)
Definition useless.c:620
static void extra_callback(GtkWidget *w, dt_iop_module_t *self)
Definition useless.c:468
commit_params(dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition useless.c:224
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
Definition useless.c:490
void gui_cleanup(dt_iop_module_t *self)
Definition useless.c:694
void cleanup_global(dt_iop_module_so_t *module)
Definition useless.c:462
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition useless.c:146
int flags()
Definition useless.c:134
gboolean force_enable(struct dt_iop_module_t *self, const gboolean current_state)
Definition useless.c:600
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition useless.c:218
void init_global(dt_iop_module_so_t *module)
Definition useless.c:448
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition useless.c:511
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
Definition useless.c:171
static const char * mask_name
Definition useless.c:211