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