Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
flip.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011-2013, 2016 johannes hanika.
4 Copyright (C) 2012 parafin.
5 Copyright (C) 2012 Richard Wonka.
6 Copyright (C) 2012-2014, 2016, 2018-2019 Tobias Ellinghaus.
7 Copyright (C) 2012, 2014 Ulrich Pegelow.
8 Copyright (C) 2013, 2020-2021 Aldric Renaudin.
9 Copyright (C) 2013-2016 Roman Lebedev.
10 Copyright (C) 2013 Simon Spannagel.
11 Copyright (C) 2013 Thomas Pryds.
12 Copyright (C) 2014 Dan Torop.
13 Copyright (C) 2015, 2018-2022 Pascal Obry.
14 Copyright (C) 2015 Pedro Côrte-Real.
15 Copyright (C) 2017 Heiko Bauke.
16 Copyright (C) 2018-2026 Aurélien PIERRE.
17 Copyright (C) 2018 Edgardo Hoszowski.
18 Copyright (C) 2018 Maurizio Paglia.
19 Copyright (C) 2018 rawfiner.
20 Copyright (C) 2019 Jacques Le Clerc.
21 Copyright (C) 2020 Diederik Ter Rahe.
22 Copyright (C) 2020 Marco.
23 Copyright (C) 2020-2021 Ralf Brown.
24 Copyright (C) 2022 Hanno Schwalm.
25 Copyright (C) 2022 Martin Bařinka.
26 Copyright (C) 2022 Philipp Lutz.
27 Copyright (C) 2023 Alynx Zhou.
28 Copyright (C) 2025 Guillaume Stutin.
29
30 darktable is free software: you can redistribute it and/or modify
31 it under the terms of the GNU General Public License as published by
32 the Free Software Foundation, either version 3 of the License, or
33 (at your option) any later version.
34
35 darktable is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 GNU General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with darktable. If not, see <http://www.gnu.org/licenses/>.
42*/
43#ifdef HAVE_CONFIG_H
44#include "common/darktable.h"
45#include "config.h"
46#endif
47#include <assert.h>
48#include <gdk/gdkkeysyms.h>
49#include <gtk/gtk.h>
50#include <inttypes.h>
51#include <math.h>
52#include <stdlib.h>
53#include <string.h>
54
55#include "common/debug.h"
56#include "common/imageio.h"
57#include "common/opencl.h"
58#include "control/conf.h"
59#include "control/control.h"
60#include "develop/develop.h"
61#include "develop/imageop.h"
62#include "develop/imageop_gui.h"
63#include "dtgtk/resetlabel.h"
64
65#include "gui/draw.h"
66#include "gui/gtk.h"
67#include "gui/presets.h"
68#include "iop/iop_api.h"
69
71
72typedef struct dt_iop_flip_params_t
73{
76
78
83
84// helper to count corners in for loops:
85static void get_corner(const int32_t *aabb, const int i, int32_t *p)
86{
87 for(int k = 0; k < 2; k++) p[k] = aabb[2 * ((i >> k) & 1) + k];
88}
89
90static void adjust_aabb(const int32_t *p, int32_t *aabb)
91{
92 aabb[0] = MIN(aabb[0], p[0]);
93 aabb[1] = MIN(aabb[1], p[1]);
94 aabb[2] = MAX(aabb[2], p[0]);
95 aabb[3] = MAX(aabb[3], p[1]);
96}
97
98const char *name()
99{
100 return _("orientation");
101}
102
103const char *aliases()
104{
105 return _("rotation|flip");
106}
107
109{
110 return IOP_GROUP_TECHNICAL;
111}
112
114{
115 return IOP_TAG_DISTORT;
116}
117
122
124{
125 return IOP_CS_RGB;
126}
127
128const char **description(struct dt_iop_module_t *self)
129{
130 return dt_iop_set_description(self, _("flip or rotate image by step of 90 degrees"), _("corrective"),
131 _("linear, RGB, scene-referred"), _("geometric, RGB"),
132 _("linear, RGB, scene-referred"));
133}
134
144 dt_image_orientation_t user_orientation)
145{
146 // Fast path: no coordinate swap needed
147 if(!(user_orientation & ORIENTATION_SWAP_XY))
148 {
149 return raw_orientation ^ user_orientation;
150 }
151
152 // When user requests XY swap, we need to swap X/Y flip bits in raw orientation
153 // Use bit manipulation for optimal performance
154 dt_image_orientation_t corrected = raw_orientation;
155
156 // Extract flip bits from raw orientation
157 const dt_image_orientation_t raw_flip_x = raw_orientation & ORIENTATION_FLIP_X;
158 const dt_image_orientation_t raw_flip_y = raw_orientation & ORIENTATION_FLIP_Y;
159
160 // Clear existing flip bits and set swapped versions
161 corrected &= ~(ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y);
162 corrected |= (raw_flip_y << 1) | (raw_flip_x >> 1); // Swap X↔Y bits efficiently
163
164 // Preserve original XY swap bit if it was set
165 corrected |= (raw_orientation & ORIENTATION_SWAP_XY);
166
167 // Apply user transformation via XOR
168 return corrected ^ user_orientation;
169}
170
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 if(old_version == 1 && new_version == 2)
175 {
176 typedef struct dt_iop_flip_params_v1_t
177 {
178 int32_t orientation;
179 } dt_iop_flip_params_v1_t;
180
181 const dt_iop_flip_params_v1_t *old = (dt_iop_flip_params_v1_t *)old_params;
184
185 *n = *d; // start with a fresh copy of default parameters
186
187 // we might be called from presets update infrastructure => there is no image
188 dt_image_orientation_t image_orientation = ORIENTATION_NONE;
189
190 if(self->dev)
191 image_orientation = dt_image_orientation(&self->dev->image_storage);
192
193 n->orientation = merge_two_orientations(image_orientation,
194 (dt_image_orientation_t)(old->orientation));
195
196 return 0;
197 }
198 return 1;
199}
200
201static void backtransform(const int32_t *x, int32_t *o, const dt_image_orientation_t orientation, int32_t iw,
202 int32_t ih)
203{
204 if(orientation & ORIENTATION_SWAP_XY)
205 {
206 o[1] = x[0];
207 o[0] = x[1];
208 const int32_t tmp = iw;
209 iw = ih;
210 ih = tmp;
211 }
212 else
213 {
214 o[0] = x[0];
215 o[1] = x[1];
216 }
217 if(orientation & ORIENTATION_FLIP_X)
218 {
219 o[0] = iw - o[0] - 1;
220 }
221 if(orientation & ORIENTATION_FLIP_Y)
222 {
223 o[1] = ih - o[1] - 1;
224 }
225}
226
228 float *const restrict points, size_t points_count)
229{
230 // if (!self->enabled) return 2;
231 const dt_iop_flip_data_t *d = (dt_iop_flip_data_t *)piece->data;
232
233 // nothing to be done if parameters are set to neutral values (no flip or swap)
234 if (d->orientation == 0) return 1;
235 __OMP_PARALLEL_FOR__(if(points_count > 500))
236 for(size_t i = 0; i < points_count * 2; i += 2)
237 {
238 float x = points[i];
239 float y = points[i + 1];
240 if(d->orientation & ORIENTATION_FLIP_X) x = piece->buf_in.width - points[i];
241 if(d->orientation & ORIENTATION_FLIP_Y) y = piece->buf_in.height - points[i + 1];
242 if(d->orientation & ORIENTATION_SWAP_XY)
243 {
244 const float yy = y;
245 y = x;
246 x = yy;
247 }
248 points[i] = x;
249 points[i + 1] = y;
250 }
251
252 return 1;
253}
255 float *const restrict points, size_t points_count)
256{
257 // if (!self->enabled) return 2;
258 const dt_iop_flip_data_t *d = (dt_iop_flip_data_t *)piece->data;
259
260 // nothing to be done if parameters are set to neutral values (no flip or swap)
261 if (d->orientation == 0) return 1;
262 __OMP_PARALLEL_FOR__(if(points_count > 500))
263 for(size_t i = 0; i < points_count * 2; i += 2)
264 {
265 float x, y;
266 if(d->orientation & ORIENTATION_SWAP_XY)
267 {
268 y = points[i];
269 x = points[i + 1];
270 }
271 else
272 {
273 x = points[i];
274 y = points[i + 1];
275 }
276 if(d->orientation & ORIENTATION_FLIP_X) x = piece->buf_in.width - x;
277 if(d->orientation & ORIENTATION_FLIP_Y) y = piece->buf_in.height - y;
278
279 points[i] = x;
280 points[i + 1] = y;
281 }
282
283 return 1;
284}
285
286void distort_mask(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece,
287 const float *const in, float *const out, const dt_iop_roi_t *const roi_in,
288 const dt_iop_roi_t *const roi_out)
289{
290 (void)pipe;
291 const dt_iop_flip_data_t *d = (dt_iop_flip_data_t *)piece->data;
292
293 const int bpp = sizeof(float);
294 const int stride = bpp * roi_in->width;
295
296 dt_imageio_flip_buffers((char *)out, (const char *)in, bpp, roi_in->width, roi_in->height,
297 roi_in->width, roi_in->height, stride, d->orientation);
298}
299
300// 1st pass: how large would the output be, given this input roi?
301// this is always called with the full buffer before processing.
302void modify_roi_out(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe,
303 struct dt_dev_pixelpipe_iop_t *piece, dt_iop_roi_t *roi_out,
304 const dt_iop_roi_t *roi_in)
305{
306 const dt_iop_flip_data_t *d = (dt_iop_flip_data_t *)piece->data;
307 *roi_out = *roi_in;
308
309 // transform whole buffer roi
310 if(d->orientation & ORIENTATION_SWAP_XY)
311 {
312 roi_out->width = roi_in->height;
313 roi_out->height = roi_in->width;
314 }
315}
316
317// 2nd pass: which roi would this operation need as input to fill the given output region?
318void modify_roi_in(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe,
319 struct dt_dev_pixelpipe_iop_t *piece,
320 const dt_iop_roi_t *roi_out, dt_iop_roi_t *roi_in)
321{
322 const dt_iop_flip_data_t *d = (dt_iop_flip_data_t *)piece->data;
323 *roi_in = *roi_out;
324 // transform aabb back to roi_in
325
326 // this aabb contains all valid points (thus the -1)
327 int32_t p[2], o[2];
328 int32_t aabb[4] = { roi_out->x, roi_out->y, roi_out->x + roi_out->width - 1, roi_out->y + roi_out->height - 1 };
329 int32_t aabb_in[4] = { INT_MAX, INT_MAX, INT_MIN, INT_MIN };
330 for(int c = 0; c < 4; c++)
331 {
332 // get corner points of roi_out
333 get_corner(aabb, c, p);
334 // backtransform aabb
335 backtransform(p, o, d->orientation, piece->buf_out.width * roi_out->scale,
336 piece->buf_out.height * roi_out->scale);
337 // transform to roi_in space, get aabb.
338 adjust_aabb(o, aabb_in);
339 }
340
341 // adjust roi_in to minimally needed region
342 roi_in->x = aabb_in[0];
343 roi_in->y = aabb_in[1];
344 // to convert valid points to widths, we need to add one
345 roi_in->width = aabb_in[2] - aabb_in[0] + 1;
346 roi_in->height = aabb_in[3] - aabb_in[1] + 1;
347
348 // sanity check.
349 float w = piece->buf_in.width * roi_out->scale;
350 float h = piece->buf_in.height * roi_out->scale;
351 roi_in->x = CLAMP(roi_in->x, 0, (int)floorf(w));
352 roi_in->y = CLAMP(roi_in->y, 0, (int)floorf(h));
353 roi_in->width = CLAMP(roi_in->width, 1, (int)ceilf(w) - roi_in->x);
354 roi_in->height = CLAMP(roi_in->height, 1, (int)ceilf(h) - roi_in->y);
355}
356
357// 3rd (final) pass: you get this input region (may be different from what was requested above),
358// do your best to fill the output region!
359int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid,
360 void *const ovoid)
361{
362 const dt_iop_roi_t *const roi_in = &piece->roi_in;
363 const dt_iop_flip_data_t *d = (dt_iop_flip_data_t *)piece->data;
364
365 const int bpp = sizeof(float) * piece->dsc_in.channels;
366 const int stride = bpp * roi_in->width;
367
368 dt_imageio_flip_buffers((char *)ovoid, (const char *)ivoid, bpp, roi_in->width, roi_in->height,
369 roi_in->width, roi_in->height, stride, d->orientation);
370 return 0;
371}
372
373#ifdef HAVE_OPENCL
374int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
375{
376 const dt_iop_roi_t *const roi_in = &piece->roi_in;
377 const dt_iop_flip_data_t *data = (dt_iop_flip_data_t *)piece->data;
379 cl_int err = -999;
380
381 const int devid = pipe->devid;
382 const int width = roi_in->width;
383 const int height = roi_in->height;
384 const int orientation = data->orientation;
385
386 const size_t sizes[] = { ROUNDUPDWD(width, devid), ROUNDUPDHT(height, devid), 1 };
387
388 dt_opencl_set_kernel_arg(devid, gd->kernel_flip, 0, sizeof(cl_mem), (void *)&dev_in);
389 dt_opencl_set_kernel_arg(devid, gd->kernel_flip, 1, sizeof(cl_mem), (void *)&dev_out);
390 dt_opencl_set_kernel_arg(devid, gd->kernel_flip, 2, sizeof(int), (void *)&width);
391 dt_opencl_set_kernel_arg(devid, gd->kernel_flip, 3, sizeof(int), (void *)&height);
392 dt_opencl_set_kernel_arg(devid, gd->kernel_flip, 4, sizeof(int), (void *)&orientation);
393 err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_flip, sizes);
394
395 if(err != CL_SUCCESS) goto error;
396 return TRUE;
397
398error:
399 dt_print(DT_DEBUG_OPENCL, "[opencl_flip] couldn't enqueue kernel! %d\n", err);
400 return FALSE;
401}
402#endif
403
405{
406 const int program = 2; // basic.cl, from programs.conf
408 self->data = gd;
409 gd->kernel_flip = dt_opencl_create_kernel(program, "flip");
410}
411
418
421{
424
425 if(p->orientation == ORIENTATION_NULL)
426 d->orientation = dt_image_orientation(&self->dev->image_storage);
427 else
428 d->orientation = p->orientation;
429
430 if(d->orientation == ORIENTATION_NONE) piece->enabled = 0;
431}
432
434{
435 piece->data = dt_calloc_align(sizeof(dt_iop_flip_data_t));
436 piece->data_size = sizeof(dt_iop_flip_data_t);
437}
438
440{
441 dt_free_align(piece->data);
442 piece->data = NULL;
443}
444
446{
449
450 p.orientation = ORIENTATION_NULL;
451 dt_gui_presets_add_generic(_("autodetect"), self->op,
452 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_NONE);
453 dt_gui_presets_update_autoapply(_("autodetect"), self->op, self->version(), 1);
454
455 p.orientation = ORIENTATION_NONE;
456 dt_gui_presets_add_generic(_("no rotation"), self->op,
457 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_NONE);
458
459 p.orientation = ORIENTATION_FLIP_HORIZONTALLY;
460 dt_gui_presets_add_generic(_("flip horizontally"), self->op,
461 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_NONE);
462
463 p.orientation = ORIENTATION_FLIP_VERTICALLY;
464 dt_gui_presets_add_generic(_("flip vertically"), self->op,
465 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_NONE);
466
467 p.orientation = ORIENTATION_ROTATE_CW_90_DEG;
468 dt_gui_presets_add_generic(_("rotate by -90 degrees"), self->op,
469 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_NONE);
470
471 p.orientation = ORIENTATION_ROTATE_CCW_90_DEG;
472 dt_gui_presets_add_generic(_("rotate by 90 degrees"), self->op,
473 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_NONE);
474
475 p.orientation = ORIENTATION_ROTATE_180_DEG;
476 dt_gui_presets_add_generic(_("rotate by 180 degrees"), self->op,
477 self->version(), &p, sizeof(p), 1, DEVELOP_BLEND_CS_NONE);
478
480}
481
483{
485
486 d->orientation = ORIENTATION_NULL;
487
488 self->default_enabled = 1;
489
491 && self->dev->image_storage.legacy_flip.user_flip != 0xff)
492 {
493 sqlite3_stmt *stmt;
495 "SELECT * FROM main.history WHERE imgid = ?1 AND operation = 'flip'", -1, &stmt,
496 NULL);
498 if(sqlite3_step(stmt) != SQLITE_ROW)
499 {
500 // convert the old legacy flip bits to a proper parameter set:
501 d->orientation
504 }
505 sqlite3_finalize(stmt);
506 }
507}
508
509static void do_rotate(dt_iop_module_t *self, uint32_t cw)
510{
512 dt_image_orientation_t orientation = p->orientation;
513
514 if(orientation == ORIENTATION_NULL) orientation = dt_image_orientation(&self->dev->image_storage);
515
516 if(cw == 0)
517 {
518 if(orientation & ORIENTATION_SWAP_XY)
519 orientation ^= ORIENTATION_FLIP_Y;
520 else
521 orientation ^= ORIENTATION_FLIP_X;
522 }
523 else
524 {
525 if(orientation & ORIENTATION_SWAP_XY)
526 orientation ^= ORIENTATION_FLIP_X;
527 else
528 orientation ^= ORIENTATION_FLIP_Y;
529 }
530 orientation ^= ORIENTATION_SWAP_XY;
531
532 p->orientation = orientation;
534}
535static void rotate_cw(GtkWidget *widget, dt_iop_module_t *self)
536{
537 do_rotate(self, 1);
538}
539static void rotate_ccw(GtkWidget *widget, dt_iop_module_t *self)
540{
541 do_rotate(self, 0);
542}
543static void _flip_h(GtkWidget *widget, dt_iop_module_t *self)
544{
546 dt_image_orientation_t orientation = p->orientation;
547
548 if(orientation == ORIENTATION_NULL) orientation = dt_image_orientation(&self->dev->image_storage);
549
550 if(orientation & ORIENTATION_SWAP_XY)
551 p->orientation = orientation ^ ORIENTATION_FLIP_VERTICALLY;
552 else
553 p->orientation = orientation ^ ORIENTATION_FLIP_HORIZONTALLY;
554
556}
557static void _flip_v(GtkWidget *widget, dt_iop_module_t *self)
558{
560 dt_image_orientation_t orientation = p->orientation;
561
562 if(orientation == ORIENTATION_NULL) orientation = dt_image_orientation(&self->dev->image_storage);
563
564 if(orientation & ORIENTATION_SWAP_XY)
565 p->orientation = orientation ^ ORIENTATION_FLIP_HORIZONTALLY;
566 else
567 p->orientation = orientation ^ ORIENTATION_FLIP_VERTICALLY;
568
570}
571
572void gui_init(struct dt_iop_module_t *self)
573{
574 self->gui_data = NULL;
576
577 self->widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_GUI_BOX_SPACING);
578
579 GtkWidget *label = dtgtk_reset_label_new(_("transform"), self, &p->orientation, sizeof(int32_t));
580 gtk_box_pack_start(GTK_BOX(self->widget), label, TRUE, TRUE, 0);
581
582 dt_iop_button_new(self, N_("rotate 90 degrees CCW."),
583 G_CALLBACK(rotate_ccw), FALSE, GDK_KEY_bracketleft, 0,
585
586 dt_iop_button_new(self, N_("rotate 90 degrees CW."),
587 G_CALLBACK(rotate_cw), FALSE, GDK_KEY_bracketright, 0,
589
590 dt_iop_button_new(self, N_("flip horizontally."), G_CALLBACK(_flip_h), FALSE, 0, 0, dtgtk_cairo_paint_flip, 1,
591 self->widget);
592
593 dt_iop_button_new(self, N_("flip vertically."), G_CALLBACK(_flip_v), FALSE, 0, 0, dtgtk_cairo_paint_flip, 0,
594 self->widget);
595}
596
597void gui_cleanup(struct dt_iop_module_t *self)
598{
599 self->gui_data = NULL;
600}
601
602// clang-format off
603// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
604// vim: shiftwidth=2 expandtab tabstop=2 cindent
605// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
606// clang-format on
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
@ DEVELOP_BLEND_CS_NONE
Definition blend.h:56
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
@ IOP_CS_RGB
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
darktable_t darktable
Definition darktable.c:181
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
#define dt_free_align(ptr)
Definition darktable.h:481
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
@ DT_DEBUG_OPENCL
Definition darktable.h:722
#define dt_free(ptr)
Definition darktable.h:456
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
sqlite3 * dt_database_get(const dt_database_t *db)
Definition database.c:3646
#define dt_database_start_transaction(db)
Definition database.h:77
#define dt_database_release_transaction(db)
Definition database.h:78
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
Definition debug.h:107
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
Definition debug.h:115
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_iop_params_t
Definition dev_history.h:41
void dtgtk_cairo_paint_refresh(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_flip(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
static void _flip_h(GtkWidget *widget, dt_iop_module_t *self)
Definition flip.c:543
int operation_tags()
Definition flip.c:113
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition flip.c:419
void distort_mask(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece, const float *const in, float *const out, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
Definition flip.c:286
const char ** description(struct dt_iop_module_t *self)
Definition flip.c:128
int default_group()
Definition flip.c:108
int distort_backtransform(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 flip.c:254
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 flip.c:227
static dt_image_orientation_t merge_two_orientations(dt_image_orientation_t raw_orientation, dt_image_orientation_t user_orientation)
Definition flip.c:143
static void rotate_cw(GtkWidget *widget, dt_iop_module_t *self)
Definition flip.c:535
static void adjust_aabb(const int32_t *p, int32_t *aabb)
Definition flip.c:90
const char * aliases()
Definition flip.c:103
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition flip.c:433
const char * name()
Definition flip.c:98
static void rotate_ccw(GtkWidget *widget, dt_iop_module_t *self)
Definition flip.c:539
void cleanup_global(dt_iop_module_so_t *self)
Definition flip.c:412
void gui_init(struct dt_iop_module_t *self)
Definition flip.c:572
static void _flip_v(GtkWidget *widget, dt_iop_module_t *self)
Definition flip.c:557
void reload_defaults(dt_iop_module_t *self)
Definition flip.c:482
static void get_corner(const int32_t *aabb, const int i, int32_t *p)
Definition flip.c:85
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition flip.c:123
int flags()
Definition flip.c:118
void gui_cleanup(struct dt_iop_module_t *self)
Definition flip.c:597
void init_presets(dt_iop_module_so_t *self)
Definition flip.c:445
static void backtransform(const int32_t *x, int32_t *o, const dt_image_orientation_t orientation, int32_t iw, int32_t ih)
Definition flip.c:201
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 flip.c:359
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition flip.c:439
struct dt_iop_flip_params_t dt_iop_flip_data_t
Definition flip.c:77
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
Definition flip.c:374
void init_global(dt_iop_module_so_t *self)
Definition flip.c:404
void modify_roi_in(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *roi_out, dt_iop_roi_t *roi_in)
Definition flip.c:318
void modify_roi_out(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece, dt_iop_roi_t *roi_out, const dt_iop_roi_t *roi_in)
Definition flip.c:302
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 flip.c:171
static void do_rotate(dt_iop_module_t *self, uint32_t cw)
Definition flip.c:509
#define DT_GUI_BOX_SPACING
Definition gtk.h:109
void dt_gui_presets_update_autoapply(const char *name, dt_dev_operation_t op, const int32_t version, const int autoapply)
void dt_gui_presets_add_generic(const char *name, dt_dev_operation_t op, const int32_t version, const void *params, const int32_t params_size, const int32_t enabled, const dt_develop_blend_colorspace_t blend_cst)
dt_image_orientation_t
Definition image.h:203
@ ORIENTATION_SWAP_XY
Definition image.h:208
@ ORIENTATION_FLIP_Y
Definition image.h:206
@ ORIENTATION_ROTATE_CCW_90_DEG
Definition image.h:215
@ ORIENTATION_NULL
Definition image.h:204
@ ORIENTATION_ROTATE_CW_90_DEG
Definition image.h:216
@ ORIENTATION_NONE
Definition image.h:205
@ ORIENTATION_FLIP_X
Definition image.h:207
@ ORIENTATION_ROTATE_180_DEG
Definition image.h:213
@ ORIENTATION_FLIP_VERTICALLY
Definition image.h:212
@ ORIENTATION_FLIP_HORIZONTALLY
Definition image.h:211
static dt_image_orientation_t dt_image_orientation(const dt_image_t *img)
Definition image.h:524
int bpp
__DT_CLONE_TARGETS__ void dt_imageio_flip_buffers(char *out, const char *in, const size_t bpp, const int wd, const int ht, const int fwd, const int fht, const int stride, const dt_image_orientation_t orientation)
Definition imageio.c:398
const char ** dt_iop_set_description(dt_iop_module_t *module, const char *main_text, const char *purpose, const char *input, const char *process, const char *output)
Definition imageop.c:3141
@ IOP_FLAGS_ALLOW_TILING
Definition imageop.h:169
@ IOP_FLAGS_UNSAFE_COPY
Definition imageop.h:177
@ IOP_FLAGS_ONE_INSTANCE
Definition imageop.h:172
@ IOP_FLAGS_TILING_FULL_ROI
Definition imageop.h:171
@ IOP_GROUP_TECHNICAL
Definition imageop.h:143
@ IOP_TAG_DISTORT
Definition imageop.h:151
GtkWidget * dt_iop_button_new(dt_iop_module_t *self, const gchar *label, GCallback callback, gboolean local, guint accel_key, GdkModifierType mods, DTGTKCairoPaintIconFunc paint, gint paintflags, GtkWidget *box)
void *const ovoid
static const float x
float *const restrict const size_t k
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
Definition opencl.c:2136
int dt_opencl_create_kernel(const int prog, const char *name)
Definition opencl.c:2030
void dt_opencl_free_kernel(const int kernel)
Definition opencl.c:2073
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
Definition opencl.c:2127
#define ROUNDUPDHT(a, b)
Definition opencl.h:82
#define ROUNDUPDWD(a, b)
Definition opencl.h:81
GtkWidget * dtgtk_reset_label_new(const gchar *text, dt_iop_module_t *module, void *param, int param_size)
Definition resetlabel.c:58
struct _GtkWidget GtkWidget
Definition splash.h:29
const struct dt_database_t * db
Definition darktable.h:779
struct dt_develop_t * develop
Definition darktable.h:770
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_image_t image_storage
Definition develop.h:259
dt_image_raw_parameters_t legacy_flip
Definition image.h:344
int32_t id
Definition image.h:319
unsigned int channels
Definition format.h:54
dt_image_orientation_t orientation
Definition lightroom.c:83
GModule *dt_dev_operation_t op
Definition imageop.h:230
dt_iop_global_data_t * data
Definition imageop.h:233
dt_iop_params_t * default_params
Definition imageop.h:307
GtkWidget * widget
Definition imageop.h:337
struct dt_develop_t * dev
Definition imageop.h:296
dt_iop_gui_data_t * gui_data
Definition imageop.h:311
gboolean default_enabled
Definition imageop.h:303
dt_iop_global_data_t * global_data
Definition imageop.h:314
dt_iop_params_t * params
Definition imageop.h:307
Region of interest passed through the pixelpipe.
Definition imageop.h:72
double scale
Definition imageop.h:74
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29