-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
pixelpipe_hb.h
341 lines (304 loc) · 14.7 KB
/
pixelpipe_hb.h
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
/*
This file is part of darktable,
Copyright (C) 2009-2023 darktable developers.
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/>.
*/
#pragma once
#include "common/atomic.h"
#include "common/image.h"
#include "common/iop_order.h"
#include "control/conf.h"
#include "develop/develop.h"
#include "develop/imageop.h"
#include "develop/pixelpipe_cache.h"
#include "imageio/imageio_common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DT_PIPECACHE_MIN 2
/**
* struct used by iop modules to connect to pixelpipe.
* data can be used to store whatever private data and
* will be freed at the end.
*/
struct dt_iop_module_t;
struct dt_iop_order_iccprofile_info_t;
typedef struct dt_dev_pixelpipe_iop_t
{
struct dt_iop_module_t *module; // the module in the dev operation stack
struct dt_dev_pixelpipe_t *pipe; // the pipe this piece belongs to
void *data; // to be used by the module to store stuff per pipe piece
void *blendop_data; // to be used by the module to store blendop per pipe piece
gboolean enabled; // used to disable parts of the pipe for export, independent on module itself.
dt_dev_request_flags_t request_histogram; // (bitwise) set if you want an histogram captured
dt_dev_histogram_collection_params_t histogram_params; // set histogram generation params
uint32_t *histogram; // pointer to histogram data; histogram_bins_count bins with 4 channels each
dt_dev_histogram_stats_t histogram_stats; // stats of captured histogram
uint32_t histogram_max[4]; // maximum levels in histogram, one per channel
float iscale; // input actually just downscaled buffer? iscale*iwidth = actual width
int iwidth, iheight; // width and height of input buffer
dt_hash_t hash; // hash of params and enabled.
int bpc; // bits per channel, 32 means float
int colors; // how many colors per pixel
dt_iop_roi_t buf_in,
buf_out; // theoretical full buffer regions of interest, as passed through modify_roi_out
dt_iop_roi_t processed_roi_in, processed_roi_out; // the actual roi that was used for processing the piece
gboolean process_cl_ready; // set this to FALSE in commit_params to temporarily disable the use of process_cl
gboolean process_tiling_ready; // set this to FALSE in commit_params to temporarily disable tiling
// the following are used internally for caching:
dt_iop_buffer_dsc_t dsc_in, dsc_out;
GHashTable *raster_masks;
} dt_dev_pixelpipe_iop_t;
typedef enum dt_dev_pixelpipe_change_t
{
DT_DEV_PIPE_UNCHANGED = 0, // no event
DT_DEV_PIPE_TOP_CHANGED = 1 << 0, // only params of top element changed
DT_DEV_PIPE_REMOVE = 1 << 1, // possibly elements of the pipe have to be removed
DT_DEV_PIPE_SYNCH
= 1 << 2, // all nodes up to end need to be synched, but no removal of module pieces is necessary
DT_DEV_PIPE_ZOOMED = 1 << 3 // zoom event, preview pipe does not need changes
} dt_dev_pixelpipe_change_t;
typedef enum dt_dev_pixelpipe_status_t
{
DT_DEV_PIXELPIPE_DIRTY = 0, // history stack changed or image new
DT_DEV_PIXELPIPE_RUNNING = 1, // pixelpipe is running
DT_DEV_PIXELPIPE_VALID = 2, // pixelpipe has finished; valid result
DT_DEV_PIXELPIPE_INVALID = 3 // pixelpipe has finished; invalid result
} dt_dev_pixelpipe_status_t;
typedef struct dt_dev_detail_mask_t
{
dt_iop_roi_t roi;
dt_hash_t hash;
float *data;
} dt_dev_detail_mask_t;
/**
* this encapsulates the pixelpipe.
* a develop module will need several of these:
* for previews and full blits to cairo and for
* the export function.
*/
typedef struct dt_dev_pixelpipe_t
{
// store history/zoom caches
dt_dev_pixelpipe_cache_t cache;
// set to TRUE in order to obsolete old cache entries on next pixelpipe run
gboolean cache_obsolete;
uint64_t runs; // used only for pixelpipe cache statistics
// input buffer
float *input;
// width and height of input buffer
int iwidth, iheight;
// input actually just downscaled buffer? iscale*iwidth = actual width
float iscale;
// dimensions of processed buffer
int processed_width, processed_height;
// this one actually contains the expected output format,
// and should be modified by process*(), if necessary.
dt_iop_buffer_dsc_t dsc;
/** work profile info of the image */
struct dt_iop_order_iccprofile_info_t *work_profile_info;
/** input profile info **/
struct dt_iop_order_iccprofile_info_t *input_profile_info;
/** output profile info **/
struct dt_iop_order_iccprofile_info_t *output_profile_info;
// instances of pixelpipe, stored in GList of dt_dev_pixelpipe_iop_t
GList *nodes;
// event flag
dt_dev_pixelpipe_change_t changed;
// pipe status
dt_dev_pixelpipe_status_t status;
gboolean loading;
gboolean input_changed;
// backbuffer (output)
uint8_t *backbuf;
size_t backbuf_size;
int backbuf_width, backbuf_height;
float backbuf_scale;
float backbuf_zoom_x, backbuf_zoom_y;
dt_hash_t backbuf_hash;
dt_pthread_mutex_t mutex, backbuf_mutex, busy_mutex;
int final_width, final_height;
// the data for the luminance mask are kept in a buffer written by demosaic or rawprepare
// as we have to scale the mask later we keep size at that stage
gboolean want_detail_mask;
struct dt_dev_detail_mask_t scharr;
// avoid cached data for processed module
gboolean nocache;
dt_imgid_t output_imgid;
// working?
gboolean processing;
// shutting down?
dt_atomic_int shutdown;
// opencl enabled for this pixelpipe?
gboolean opencl_enabled;
// opencl error detected?
gboolean opencl_error;
// running in a tiling context?
gboolean tiling;
// should this pixelpipe display a mask in the end?
dt_dev_pixelpipe_display_mask_t mask_display;
// should this pixelpipe completely suppressed the blendif module?
gboolean bypass_blendif;
// input data based on this timestamp:
int input_timestamp;
uint32_t average_delay;
dt_dev_pixelpipe_type_t type;
// the final output pixel format this pixelpipe will be converted to
dt_imageio_levels_t levels;
// opencl device that has been locked for this pipe.
int devid;
// image struct as it was when the pixelpipe was initialized. copied to avoid race conditions.
dt_image_t image;
// the user might choose to overwrite the output color space and rendering intent.
dt_colorspaces_color_profile_type_t icc_type;
gchar *icc_filename;
dt_iop_color_intent_t icc_intent;
// snapshot of modules
GList *iop;
// snapshot of modules iop_order
GList *iop_order_list;
// snapshot of mask list
GList *forms;
// the masks generated in the pipe for later reusal are inside dt_dev_pixelpipe_iop_t
gboolean store_all_raster_masks;
} dt_dev_pixelpipe_t;
struct dt_develop_t;
// report pipe->type as textual string
const char *dt_dev_pixelpipe_type_to_str(int pipe_type);
// inits the pixelpipe with plain passthrough input/output and empty input and default caching settings.
gboolean dt_dev_pixelpipe_init(dt_dev_pixelpipe_t *pipe);
// inits the preview pixelpipe with plain passthrough input/output and empty input and default caching
// settings.
gboolean dt_dev_pixelpipe_init_preview(dt_dev_pixelpipe_t *pipe);
gboolean dt_dev_pixelpipe_init_preview2(dt_dev_pixelpipe_t *pipe);
// inits the pixelpipe with settings optimized for full-image export
// (no history stack cache)
gboolean dt_dev_pixelpipe_init_export(dt_dev_pixelpipe_t *pipe,
const int32_t width,
const int32_t height,
const int levels,
const gboolean store_masks);
// inits the pixelpipe with settings optimized for thumbnail export
// (no history stack cache)
gboolean dt_dev_pixelpipe_init_thumbnail(dt_dev_pixelpipe_t *pipe,
const int32_t width,
const int32_t height);
// inits all but the pixel caches, so you can't actually process an
// image (just get dimensions and distortions)
gboolean dt_dev_pixelpipe_init_dummy(dt_dev_pixelpipe_t *pipe,
const int32_t width,
const int32_t height);
// inits the pixelpipe with given cacheline size and number of
// entries. returns TRUE in case of success
gboolean dt_dev_pixelpipe_init_cached(dt_dev_pixelpipe_t *pipe,
const size_t size,
const int32_t entries,
const size_t memlimit);
// constructs a new input buffer from given RGB float array.
void dt_dev_pixelpipe_set_input(dt_dev_pixelpipe_t *pipe,
struct dt_develop_t *dev,
float *input,
const int width,
const int height,
const float iscale);
// set some metadata for colorout to avoid race conditions.
void dt_dev_pixelpipe_set_icc(dt_dev_pixelpipe_t *pipe,
const dt_colorspaces_color_profile_type_t icc_type,
const gchar *icc_filename,
const dt_iop_color_intent_t icc_intent);
// returns the dimensions of the full image after processing.
void dt_dev_pixelpipe_get_dimensions(dt_dev_pixelpipe_t *pipe,
struct dt_develop_t *dev,
const int width_in,
const int height_in,
int *width,
int *height);
// destroys all allocated data.
void dt_dev_pixelpipe_cleanup(dt_dev_pixelpipe_t *pipe);
// wrapper for cleanup_nodes, create_nodes, synch_all and synch_top,
// decides upon changed event which one to take on. also locks
// dev->history_mutex.
void dt_dev_pixelpipe_change(dt_dev_pixelpipe_t *pipe, struct dt_develop_t *dev);
// cleanup all nodes except clean input/output
void dt_dev_pixelpipe_cleanup_nodes(dt_dev_pixelpipe_t *pipe);
// sync with develop_t history stack from scratch (new node added, have to pop old ones)
void dt_dev_pixelpipe_create_nodes(dt_dev_pixelpipe_t *pipe, struct dt_develop_t *dev);
// sync with develop_t history stack by just copying the top item params (same op, new params on top)
void dt_dev_pixelpipe_synch_all(dt_dev_pixelpipe_t *pipe, struct dt_develop_t *dev);
// adjust output node according to history stack (history pop event)
void dt_dev_pixelpipe_synch_top(dt_dev_pixelpipe_t *pipe, struct dt_develop_t *dev);
// force a rebuild of the pipe, needed when a module order is changed for example
void dt_dev_pixelpipe_rebuild(struct dt_develop_t *dev);
// switch on details mask processing
void dt_dev_pixelpipe_usedetails(dt_dev_pixelpipe_t *pipe);
// process region of interest of pixels. returns TRUE if pipe was altered during processing.
gboolean dt_dev_pixelpipe_process(dt_dev_pixelpipe_t *pipe,
struct dt_develop_t *dev,
const int x,
const int y,
const int width,
const int height,
const float scale,
const int devid);
// convenience method that does not gamma-compress the image.
gboolean dt_dev_pixelpipe_process_no_gamma(dt_dev_pixelpipe_t *pipe,
struct dt_develop_t *dev,
const int x,
const int y,
const int width,
const int height,
const float scale);
// disable given op and all that comes after it in the pipe:
void dt_dev_pixelpipe_disable_after(dt_dev_pixelpipe_t *pipe, const char *op);
// disable given op and all that comes before it in the pipe:
void dt_dev_pixelpipe_disable_before(dt_dev_pixelpipe_t *pipe, const char *op);
// disable given op only:
void dt_dev_pixelpipe_module_enabled(dt_dev_pixelpipe_t *pipe, const char *op, const gboolean enable);
// helper function to pass a raster mask through a (so far) processed pipe
float *dt_dev_get_raster_mask(const struct dt_dev_pixelpipe_iop_t *piece,
const struct dt_iop_module_t *raster_mask_source,
const dt_mask_id_t raster_mask_id,
const struct dt_iop_module_t *target_module,
gboolean *free_mask);
// some helper functions related to the details mask interface
void dt_dev_clear_scharr_mask(dt_dev_pixelpipe_t *pipe);
gboolean dt_dev_write_scharr_mask(dt_dev_pixelpipe_iop_t *piece,
float *const rgb,
const dt_iop_roi_t *const roi_in,
const gboolean mode);
#ifdef HAVE_OPENCL
int dt_dev_write_scharr_mask_cl(dt_dev_pixelpipe_iop_t *piece,
cl_mem in,
const dt_iop_roi_t *const roi_in,
const gboolean mode);
#endif
/* specialized version of dt_print for pixelpipe debugging */
void dt_print_pipe_ext(const char *title,
const dt_dev_pixelpipe_t *pipe,
const struct dt_iop_module_t *mod,
const int device,
const dt_iop_roi_t *roi_in,
const dt_iop_roi_t *roi_out,
const char *msg, ...)
__attribute__((format(printf, 7, 8)));
// helper function writing the pipe-processed ctmask data to dest
float *dt_dev_distort_detail_mask(dt_dev_pixelpipe_t *pipe,
float *src,
const struct dt_iop_module_t *target_module);
#ifdef __cplusplus
} // extern "C"
#endif /* __cplusplus */
// clang-format off
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
// vim: shiftwidth=2 expandtab tabstop=2 cindent
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
// clang-format on