forked from darktable-org/darktable
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimageop.h
More file actions
452 lines (398 loc) · 21.4 KB
/
Copy pathimageop.h
File metadata and controls
452 lines (398 loc) · 21.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
/*
This file is part of darktable,
copyright (c) 2009--2012 johannes hanika.
copyright (c) 2011 henrik andersson.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DT_DEVELOP_IMAGEOP_H
#define DT_DEVELOP_IMAGEOP_H
#include "common/darktable.h"
#include "control/settings.h"
#include "develop/pixelpipe.h"
#include "dtgtk/togglebutton.h"
#include <gmodule.h>
#include <gtk/gtk.h>
#include <sched.h>
struct dt_develop_t;
struct dt_dev_pixelpipe_t;
struct dt_dev_pixelpipe_iop_t;
struct dt_iop_roi_t;
struct dt_develop_blend_params_t;
struct dt_develop_tiling_t;
#define IOP_GROUP_BASIC 1
#define IOP_GROUP_COLOR 2
#define IOP_GROUP_CORRECT 4
#define IOP_GROUP_EFFECT 8
#define IOP_GROUP_TONE 16
#define IOP_SPECIAL_GROUP_ACTIVE_PIPE 32
#define IOP_SPECIAL_GROUP_USER_DEFINED 64
#define IOP_TAG_DISTORT 1
#define IOP_TAG_DECORATION 2
// might be some other filters togglable by user?
//#define IOP_TAG_SLOW 4
//#define IOP_TAG_DETAIL_FIX 8
#define IOP_GROUP_ALL (IOP_GROUP_BASIC|IOP_GROUP_COLOR|IOP_GROUP_CORRECT|IOP_GROUP_EFFECT)
/** Flag for the iop module to be enabled/included by default when creating a style */
#define IOP_FLAGS_INCLUDE_IN_STYLES 1
#define IOP_FLAGS_SUPPORTS_BLENDING 2 // Does provide blending modes
#define IOP_FLAGS_DEPRECATED 4
#define IOP_FLAGS_BLEND_ONLY_LIGHTNESS 8 // Does only blend with L-channel in Lab space. Keeps a, b of original image.
#define IOP_FLAGS_ALLOW_TILING 16 // Does allow tile-wise processing (valid for CPU and GPU processing)
#define IOP_FLAGS_HIDDEN 32 // Hide the iop from userinterface
#define IOP_FLAGS_TILING_FULL_ROI 64 // Tiling code has to expect arbitrary roi's for this module (incl. flipping, mirroring etc.)
typedef struct dt_iop_params_t
{
int keep;
}
dt_iop_params_t;
typedef void dt_iop_gui_data_t;
typedef void dt_iop_data_t;
typedef void dt_iop_global_data_t;
/** part of the module which only contains the cached dlopen stuff. */
struct dt_iop_module_so_t;
struct dt_iop_module_t;
typedef struct dt_iop_module_so_t
{
/** opened module. */
GModule *module;
/** string identifying this operation. */
dt_dev_operation_t op;
/** other stuff that may be needed by the module, not only in gui mode. inited only once, has to be read-only then. */
dt_iop_global_data_t *data;
/** gui is also only inited once at startup. */
dt_iop_gui_data_t *gui_data;
/** which results in this widget here, too. */
GtkWidget *widget;
/** this initializes static, hardcoded presets for this module and is called only once per run of dt. */
void (*init_presets) (struct dt_iop_module_so_t *self);
/** called once per module, at startup. */
void (*init_global) (struct dt_iop_module_so_t *self);
/** called once per module, at shutdown. */
void (*cleanup_global) (struct dt_iop_module_so_t *self);
/** callbacks, loaded once, referenced by the instances. */
int (*version) ();
const char* (*name) ();
int (*groups) ();
int (*flags) ();
int (*operation_tags) ();
int (*operation_tags_filter) ();
int (*output_bpp) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
void (*tiling_callback) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out, struct dt_develop_tiling_t *tiling);
void (*gui_reset) (struct dt_iop_module_t *self);
void (*gui_update) (struct dt_iop_module_t *self);
void (*gui_init) (struct dt_iop_module_t *self);
void (*gui_cleanup) (struct dt_iop_module_t *self);
void (*gui_post_expose) (struct dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery);
void (*gui_focus) (struct dt_iop_module_t *self, gboolean in);
/** Optional callback for keyboard accelerators */
void (*init_key_accels)(struct dt_iop_module_so_t *so);
void (*connect_key_accels)(struct dt_iop_module_t *self);
void (*disconnect_key_accels)(struct dt_iop_module_t *self);
int (*mouse_leave) (struct dt_iop_module_t *self);
int (*mouse_moved) (struct dt_iop_module_t *self, double x, double y, int which);
int (*button_released) (struct dt_iop_module_t *self, double x, double y, int which, uint32_t state);
int (*button_pressed) (struct dt_iop_module_t *self, double x, double y, int which, int type, uint32_t state);
int (*scrolled) (struct dt_iop_module_t *self, double x, double y, int up, uint32_t state);
void (*configure) (struct dt_iop_module_t *self, int width, int height);
void (*init) (struct dt_iop_module_t *self); // this MUST set params_size!
void (*cleanup) (struct dt_iop_module_t *self);
void (*init_pipe) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
void (*commit_params) (struct dt_iop_module_t *self, struct dt_iop_params_t *params, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
void (*reload_defaults) (struct dt_iop_module_t *self);
void (*cleanup_pipe) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
void (*modify_roi_in) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, const struct dt_iop_roi_t *roi_out, struct dt_iop_roi_t *roi_in);
void (*modify_roi_out) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, struct dt_iop_roi_t *roi_out, const struct dt_iop_roi_t *roi_in);
int (*legacy_params) (struct dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version);
void (*process) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out);
void (*process_tiling) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out, const int bpp);
int (*process_cl) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out);
int (*process_tiling_cl) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out, const int bpp);
}
dt_iop_module_so_t;
typedef struct dt_iop_module_t
{
/** opened module. */
GModule *module;
/** string identifying this operation. */
dt_dev_operation_t op;
/** used to identify this module in the history stack. */
int32_t instance;
/** order in which plugins are stacked. */
int32_t priority;
/** module sets this if the enable checkbox should be hidden. */
int32_t hide_enable_button;
/** set to 1 if you want an input color picked during next eval. gui mode only. */
int32_t request_color_pick;
/** set to 1 if you want the mask to be transfered into alpha channel during next eval. gui mode only. */
int32_t request_mask_display;
/** bounding box in which the mean color is requested. */
float color_picker_box[4];
/** single point to pick if in point mode */
float color_picker_point[2];
/** place to store the picked color of module input. */
float picked_color[3], picked_color_min[3], picked_color_max[3];
/** place to store the picked color of module output (before blending). */
float picked_output_color[3], picked_output_color_min[3], picked_output_color_max[3];
/** reference for dlopened libs. */
darktable_t *dt;
/** the module is used in this develop module. */
struct dt_develop_t *dev;
/** non zero if this node should be processed. */
int32_t enabled, default_enabled, factory_enabled;
/** parameters for the operation. will be replaced by history revert. */
dt_iop_params_t *params, *default_params, *factory_params;
/** size of individual params struct. */
int32_t params_size;
/** parameters needed if a gui is attached. will be NULL if in export/batch mode. */
dt_iop_gui_data_t *gui_data;
/** other stuff that may be needed by the module, not only in gui mode. */
dt_iop_global_data_t *data;
/** blending params */
struct dt_develop_blend_params_t *blend_params, *default_blendop_params;
/** holder for blending ui control */
gpointer blend_data;
/** child widget which is added to the GtkExpander. copied from module_so_t. */
GtkWidget *widget;
/** off button, somewhere in header, common to all plug-ins. */
GtkDarktableToggleButton *off;
/** this is the module header, contains labe and buttons */
GtkWidget *header;
/** button used to show/hide this module in the plugin list. */
GtkWidget *showhide;
/** expander containing the widget. */
GtkWidget *expander;
/** reset parameters button */
GtkWidget *reset_button;
/** show preset menu button */
GtkWidget *presets_button;
/** fusion slider */
GtkWidget *fusion_slider;
/** list of closures: show, enable/disable */
GSList *accel_closures;
GSList *accel_closures_local;
gboolean local_closures_connected;
/** the correspoinding SO object */
dt_iop_module_so_t *so;
/** version of the parameters in the database. */
int (*version) ();
/** get name of the module, to be translated. */
const char* (*name) ();
/** get the groups this module belongs to. */
int (*groups) ();
/** get the iop module flags. */
int (*flags) ();
int (*operation_tags) ();
int (*operation_tags_filter) ();
/** how many bytes per pixel in the output. */
int (*output_bpp) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
/** report back info for tiling: memory usage and overlap. Memory usage: factor * intput_size + overhead */
void (*tiling_callback) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out, struct dt_develop_tiling_t *tiling);
/** callback methods for gui. */
/** synch gtk interface with gui params, if necessary. */
void (*gui_update) (struct dt_iop_module_t *self);
/** reset ui to defaults */
void (*gui_reset) (struct dt_iop_module_t *self);
/** construct widget. */
void (*gui_init) (struct dt_iop_module_t *self);
/** destroy widget. */
void (*gui_cleanup) (struct dt_iop_module_t *self);
/** optional method called after darkroom expose. */
void (*gui_post_expose) (struct dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery);
/** optional callback to be notified if the module acquires gui focus/loses it. */
void (*gui_focus) (struct dt_iop_module_t *self, gboolean in);
/** optional event callbacks */
int (*mouse_leave) (struct dt_iop_module_t *self);
int (*mouse_moved) (struct dt_iop_module_t *self, double x, double y, int which);
int (*button_released) (struct dt_iop_module_t *self, double x, double y, int which, uint32_t state);
int (*button_pressed) (struct dt_iop_module_t *self, double x, double y, int which, int type, uint32_t state);
int (*key_pressed) (struct dt_iop_module_t *self, uint16_t which);
int (*scrolled) (struct dt_iop_module_t *self, double x, double y, int up, uint32_t state);
void (*configure) (struct dt_iop_module_t *self, int width, int height);
void (*init) (struct dt_iop_module_t *self); // this MUST set params_size!
void (*cleanup) (struct dt_iop_module_t *self);
/** this inits the piece of the pipe, allocing piece->data as necessary. */
void (*init_pipe) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
/** this resets the params to factory defaults. used at the beginning of each history synch. */
/** this commits (a mutex will be locked to synch gegl/gui) the given history params to the gegl pipe piece. */
void (*commit_params) (struct dt_iop_module_t *self, struct dt_iop_params_t *params, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
/** this is the chance to update default parameters, after the full raw is loaded. */
void (*reload_defaults) (struct dt_iop_module_t *self);
/** this destroys all (gegl etc) resources needed by the piece of the pipeline. */
void (*cleanup_pipe) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
void (*modify_roi_in) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, const struct dt_iop_roi_t *roi_out, struct dt_iop_roi_t *roi_in);
void (*modify_roi_out) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, struct dt_iop_roi_t *roi_out, const struct dt_iop_roi_t *roi_in);
int (*legacy_params) (struct dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version);
/** this is the temp homebrew callback to operations, as long as gegl is so slow.
* x,y, and scale are just given for orientation in the framebuffer. i and o are
* scaled to the same size width*height and contain a max of 3 floats. other color
* formats may be filled by this callback, if the pipeline can handle it. */
void (*process) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out);
/** a tiling variant of process(). */
void (*process_tiling) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out, const int bpp);
/** the opencl equivalent of process(). */
int (*process_cl) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out);
/** a tiling variant of process_cl(). */
int (*process_tiling_cl) (struct dt_iop_module_t *self, struct dt_dev_pixelpipe_iop_t *piece, void *i, void *o, const struct dt_iop_roi_t *roi_in, const struct dt_iop_roi_t *roi_out, const int bpp);
/** Key accelerator registration callbacks */
void (*connect_key_accels)(struct dt_iop_module_t *self);
void (*disconnect_key_accels)(struct dt_iop_module_t *self);
}
dt_iop_module_t;
/** loads and inits the modules in the plugins/ directory. */
void dt_iop_load_modules_so();
/** cleans up the dlopen refs. */
void dt_iop_unload_modules_so();
/** returns a list of instances referencing stuff loaded in load_modules_so. */
GList *dt_iop_load_modules(struct dt_develop_t *dev);
/** calls module->cleanup and closes the dl connection. */
void dt_iop_cleanup_module(dt_iop_module_t *module);
/** initialize pipe. */
void dt_iop_init_pipe(struct dt_iop_module_t *module, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
/** checks if iop do have an ui */
gboolean dt_iop_is_hidden(dt_iop_module_t *module);
/** updates the gui params and the enabled switch. */
void dt_iop_gui_update(dt_iop_module_t *module);
/** reset the ui to its defaults */
void dt_iop_gui_reset(dt_iop_module_t *module);
/** set expanded state of iop */
void dt_iop_gui_set_expanded(dt_iop_module_t *module, gboolean expanded);
/** commits params and updates piece hash. */
void dt_iop_commit_params(dt_iop_module_t *module, struct dt_iop_params_t *params, struct dt_develop_blend_params_t * blendop_params, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece);
/** creates a label widget for the expander, with callback to enable/disable this module. */
GtkWidget *dt_iop_gui_get_expander(dt_iop_module_t *module);
/** get the widget of plugin ui in expander */
GtkWidget *dt_iop_gui_get_widget(dt_iop_module_t *module);
/** get the eventbox of plugin ui in expander */
GtkWidget *dt_iop_gui_get_pluginui(dt_iop_module_t *module);
/** requests the focus for this plugin (to draw overlays over the center image) */
void dt_iop_request_focus(dt_iop_module_t *module);
/** loads default settings from database. */
void dt_iop_load_default_params(dt_iop_module_t *module);
/** reloads certain gui/param defaults when the image was switched. */
void dt_iop_reload_defaults(dt_iop_module_t *module);
/** let plugins have breakpoints: */
int dt_iop_breakpoint(struct dt_develop_t *dev, struct dt_dev_pixelpipe_t *pipe);
/** allow plugins to relinquish CPU and go to sleep for some time */
void dt_iop_nap(uint32_t usec);
/** colorspace enums */
typedef enum dt_iop_colorspace_type_t
{
iop_cs_RAW,
iop_cs_Lab,
iop_cs_rgb
}
dt_iop_colorspace_type_t;
/** find which colorspace the module works within */
dt_iop_colorspace_type_t dt_iop_module_colorspace(const dt_iop_module_t *module);
/** flip according to orientation bits, also zoom to given size. */
void dt_iop_flip_and_zoom_8( const uint8_t *in, int32_t iw, int32_t ih, uint8_t *out, int32_t ow, int32_t oh, const int32_t orientation, uint32_t *width, uint32_t *height);
/** for homebrew pixel pipe: zoom pixel array. */
void dt_iop_clip_and_zoom(float *out, const float *const in, const struct dt_iop_roi_t *const roi_out, const struct dt_iop_roi_t * const roi_in, const int32_t out_stride, const int32_t in_stride);
/** clip and zoom mosaiced image without demosaicing it uint16_t -> float4 */
void
dt_iop_clip_and_zoom_demosaic_half_size(
float *out,
const uint16_t *const in,
const struct dt_iop_roi_t *const roi_out,
const struct dt_iop_roi_t *const roi_in,
const int32_t out_stride,
const int32_t in_stride,
const uint32_t filters);
void
dt_iop_clip_and_zoom_demosaic_half_size_f(
float *out,
const float *const in,
const struct dt_iop_roi_t *const roi_out,
const struct dt_iop_roi_t *const roi_in,
const int32_t out_stride,
const int32_t in_stride,
const uint32_t filters,
const float clip);
/** as dt_iop_clip_and_zoom, but for rgba 8-bit channels. */
void dt_iop_clip_and_zoom_8(const uint8_t *i, int32_t ix, int32_t iy, int32_t iw, int32_t ih, int32_t ibw, int32_t ibh,
uint8_t *o, int32_t ox, int32_t oy, int32_t ow, int32_t oh, int32_t obw, int32_t obh);
void dt_iop_YCbCr_to_RGB(const float *yuv, float *rgb);
void dt_iop_RGB_to_YCbCr(const float *rgb, float *yuv);
dt_iop_module_t *get_colorout_module();
/** returns the localized plugin name for a given op name. must not be freed. */
gchar *dt_iop_get_localized_name(const gchar * op);
/** takes four points (x,y) in two arrays and fills the cubic coefficients a, such that y = [X] * a, where
* [X] is the matrix containing all x^3 x^2 x^1 x^0 lines for all four x. */
void dt_iop_estimate_cubic(const float *const x, const float *const y, float *a);
/** evaluates the cubic fit, i.e. returns y = a^t [x^3 x^2 x^1 1] */
static inline float dt_iop_eval_cubic(const float *const a, const float x)
{
// could be sse4.1 _mm_dot_ps
const float x4[4] = {x*x*x, x*x, x, 1.0f};
return a[3]*x4[3] + a[2]*x4[2] + a[1]*x4[1] + a[0]*x4[0];
}
/** estimates an exponential form f(x) = a*x^g from a few (num) points (x, y).
* the largest point should be (1.0, y) to really get good data. */
static inline void dt_iop_estimate_exp(const float *const x, const float *const y, const int num, float *coeff)
{
// map every thing to y = y0*(x/x0)^g
// and fix (x0,y0) as the last point.
// assume (x,y) pairs are ordered by ascending x, so this is the last point:
float x0 = x[num-1], y0 = y[num-1];
float g = 0.0f;
int cnt = 0;
// solving for g yields
// g = log(y/y0)/log(x/x0)
//
// average that over the course of the other samples:
for(int k=0;k<num-1;k++)
{
const float yy = y[k]/y0, xx = x[k]/x0;
if(yy > 0.0f && xx > 0.0f)
{
const float gg = logf(y[k]/y0)/log(x[k]/x0);
g += gg;
cnt ++;
}
}
if(cnt)
g *= 1.0f/cnt;
else
g = 1.0f;
coeff[0] = 1.0f/x0;
coeff[1] = y0;
coeff[2] = g;
}
/** evaluates the exp fit. */
static inline float dt_iop_eval_exp(const float *const coeff, const float x)
{
return coeff[1] * powf(x*coeff[0], coeff[2]);
}
/** Connects common accelerators to an iop module */
void dt_iop_connect_common_accels(dt_iop_module_t *module);
/** Copy alpha channel 1:1 from input to output */
static inline void dt_iop_alpha_copy(const void *ivoid, void *ovoid, const int width, const int height)
{
#ifdef _OPENMP
#pragma omp parallel for schedule(static) default(none) shared(ovoid,ivoid)
#endif
for(int j=0; j<height; j++)
{
const float *in = ((const float *)ivoid)+4*width*j+3;
float *out = ((float *)ovoid)+4*width*j+3;
for(int i=0; i<width; i++)
{
*out = *in;
out += 4;
in += 4;
}
}
}
#endif
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
// vim: shiftwidth=2 expandtab tabstop=2 cindent
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-space on;