Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
pixelpipe_rawdetail.c
Go to the documentation of this file.
1
11#include "pixel/interpolation.h"
13
14float *dt_dev_retrieve_rawdetail_mask(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *target_module)
15{
16 const dt_dev_pixelpipe_iop_t *detailmask_piece = NULL;
17 for(GList *iter = g_list_first(pipe->nodes); iter; iter = g_list_next(iter))
18 {
19 const dt_dev_pixelpipe_iop_t *candidate = (const dt_dev_pixelpipe_iop_t *)iter->data;
20 if(!candidate) continue;
21 if(candidate->module == target_module) break;
22 if(candidate->enabled && !strcmp(candidate->module->op, "detailmask"))
23 detailmask_piece = candidate;
24 }
25
26 dt_dev_pixelpipe_t *mutable_pipe = (dt_dev_pixelpipe_t *)pipe;
27 const uint64_t mask_hash = detailmask_piece ? dt_dev_pixelpipe_rawdetail_mask_hash(detailmask_piece)
29
30 if(mask_hash == DT_PIXELPIPE_CACHE_HASH_INVALID) return NULL;
31
32 if(pipe->rawdetail_mask_hash != mask_hash)
33 {
35 if(IS_NULL_PTR(entry)) return NULL;
36
37 dt_dev_clear_rawdetail_mask(mutable_pipe);
39 mutable_pipe->rawdetail_mask_hash = mask_hash;
40 memcpy(&mutable_pipe->rawdetail_mask_roi, &detailmask_piece->roi_out, sizeof(dt_iop_roi_t));
41 }
42
43 void *mask = NULL;
44 if(!dt_dev_pixelpipe_cache_peek(pipe->rawdetail_mask_hash, &mask, NULL, pipe->devid, NULL))
45 return NULL;
46
47 return (float *)mask;
48}
49
50float *dt_dev_distort_detail_mask(const dt_dev_pixelpipe_t *pipe, float *src,
51 const dt_iop_module_t *target_module)
52{
53 if(dt_dev_retrieve_rawdetail_mask(pipe, target_module) == NULL) return NULL;
54 gboolean valid = FALSE;
55 const dt_dev_pixelpipe_iop_t *target_piece = NULL;
56 GList *source_iter = NULL;
57 for(GList *iter = g_list_first(pipe->nodes); iter; iter = g_list_next(iter))
58 {
59 const dt_dev_pixelpipe_iop_t *candidate = (dt_dev_pixelpipe_iop_t *)iter->data;
60 if(candidate->module == target_module) target_piece = candidate;
61 if((IS_NULL_PTR(source_iter)) && (!strcmp(candidate->module->op, "detailmask")) && candidate->enabled)
62 {
63 valid = TRUE;
64 source_iter = iter;
65 }
66 }
67
68 if(!valid) return NULL;
69 dt_vprint(DT_DEBUG_MASKS, "[dt_dev_distort_detail_mask] (%ix%i) for module %s\n",
70 pipe->rawdetail_mask_roi.width, pipe->rawdetail_mask_roi.height, target_module->op);
71
72 float *resmask = src;
73 float *inmask = src;
74 dt_iop_roi_t current_roi = pipe->rawdetail_mask_roi;
75 if(source_iter)
76 {
77 /* The side-band detail mask is stored in the output geometry of the
78 * hidden `detailmask` stage. Start warping at the next node exactly like
79 * raster masks do, otherwise we would re-apply the source transform to a
80 * buffer that is already expressed in source output coordinates. */
81 for(GList *iter = g_list_next(source_iter); iter; iter = g_list_next(iter))
82 {
83 dt_dev_pixelpipe_iop_t *module = (dt_dev_pixelpipe_iop_t *)iter->data;
84 if(module->enabled
85 && !dt_dev_pixelpipe_activemodule_disables_currentmodule(module->module->dev, module->module))
86 {
87 if(module->module->distort_mask
88 && !(!strcmp(module->module->op, "finalscale")
89 && module->roi_in.width == 0
90 && module->roi_in.height == 0))
91 {
93 (size_t)module->roi_out.width * module->roi_out.height, 0);
94 dt_vprint(DT_DEBUG_MASKS, " %s %ix%i -> %ix%i\n", module->module->op,
95 module->roi_in.width, module->roi_in.height,
96 module->roi_out.width, module->roi_out.height);
97 module->module->distort_mask(module->module, (dt_dev_pixelpipe_t *)pipe, module, inmask, tmp,
98 &module->roi_in, &module->roi_out);
99 resmask = tmp;
100 if(inmask != src) dt_pixelpipe_cache_free_align(inmask);
101 inmask = tmp;
102 current_roi = module->roi_out;
103 }
104 else if(!module->module->distort_mask
105 && (module->roi_in.width != module->roi_out.width
106 || module->roi_in.height != module->roi_out.height
107 || module->roi_in.x != module->roi_out.x
108 || module->roi_in.y != module->roi_out.y))
109 fprintf(stderr, "FIXME: module `%s' changed the roi from %d x %d @ %d / %d to %d x %d | %d / %d but doesn't have "
110 "distort_mask() implemented!\n", module->module->op, module->roi_in.width,
111 module->roi_in.height, module->roi_in.x, module->roi_in.y,
112 module->roi_out.width, module->roi_out.height, module->roi_out.x,
113 module->roi_out.y);
114
115 if(module->module == target_module) break;
116 }
117 }
118 }
119
120 if(!IS_NULL_PTR(target_piece)
121 && (current_roi.scale != target_piece->roi_out.scale
122 || current_roi.width != target_piece->roi_out.width
123 || current_roi.height != target_piece->roi_out.height
124 || current_roi.x != target_piece->roi_out.x
125 || current_roi.y != target_piece->roi_out.y))
126 {
127 /* The cached raw-detail mask is kept at the full-resolution source ROI.
128 * When the downstream walk stops before matching the consumer output ROI,
129 * finish by resampling/cropping once into the consumer geometry, just like
130 * initialscale would do for the pixel buffer. */
132 (size_t)target_piece->roi_out.width * target_piece->roi_out.height, 0);
134 dt_interpolation_resample_roi_1c(itor, tmp, &target_piece->roi_out, inmask, &current_roi);
135 if(inmask != src) dt_pixelpipe_cache_free_align(inmask);
136 inmask = tmp;
137 resmask = tmp;
138 }
139
140 return resmask;
141}
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
gboolean dt_dev_pixelpipe_activemodule_disables_currentmodule(struct dt_develop_t *dev, struct dt_iop_module_t *current_module)
const struct dt_interpolation * dt_interpolation_new(enum dt_interpolation_type type)
void dt_interpolation_resample_roi_1c(const struct dt_interpolation *itor, float *out, const dt_iop_roi_t *const roi_out, const float *const in, const dt_iop_roi_t *const roi_in)
@ DT_INTERPOLATION_USERPREF_WARP
@ DT_DEBUG_MASKS
Definition logging.h:62
void void void dt_vprint(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
dt_print() that additionally requires DT_DEBUG_VERBOSE to be enabled, i.e. both -d <channel> and -d v...
#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
uint64_t dt_dev_pixelpipe_rawdetail_mask_hash(const dt_dev_pixelpipe_iop_t *piece)
Definition pixelpipe.c:45
void dt_dev_clear_rawdetail_mask(dt_dev_pixelpipe_t *pipe)
Release the side-band detail mask cache reference currently owned by the pipeline.
Definition pixelpipe.c:64
void dt_dev_pixelpipe_cache_ref_count_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Increase/Decrease the reference count on the cache line as to prevent LRU item removal....
gboolean dt_dev_pixelpipe_cache_peek(const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry, const int preferred_devid, void **cl_mem_output)
Non-owning lookup of an existing cache line.
dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry(const uint64_t hash)
Get an internal reference to the cache entry matching hash. If you are going to access this entry mor...
#define DT_PIXELPIPE_CACHE_HASH_INVALID
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
#define dt_pixelpipe_cache_free_align(mem)
float * dt_dev_distort_detail_mask(const dt_dev_pixelpipe_t *pipe, float *src, const dt_iop_module_t *target_module)
float * dt_dev_retrieve_rawdetail_mask(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *target_module)
unsigned __int64 uint64_t
Definition strptime.c:75
struct dt_iop_module_t *void * data
uint64_t rawdetail_mask_hash
struct dt_iop_roi_t rawdetail_mask_roi
dt_dev_operation_t op
Definition imageop.h:259
Region of interest passed through the pixelpipe.
Definition format.h:49
double scale
Definition format.h:51
int width
Definition format.h:50
int height
Definition format.h:50