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
15 const uint64_t output_hash)
16{
17 if(g_strcmp0(piece->module->op, "detailmask")) return TRUE;
19 if(mask_hash == DT_PIXELPIPE_CACHE_HASH_INVALID || pipe->rawdetail_mask_hash == mask_hash) return TRUE;
20
21 // Looked up and referenced at once, as the stage's process() keeps the mask it finds.
22 if(dt_dev_pixelpipe_cache_ref_entry_by_hash(mask_hash, NULL, NULL))
23 {
25 pipe->rawdetail_mask_hash = mask_hash;
26 memcpy(&pipe->rawdetail_mask_roi, &piece->roi_out, sizeof(dt_iop_roi_t));
27 return TRUE;
28 }
29
30 /* Pipes run one at a time, so nothing else holds this output while we are here: it goes, and
31 * neither lookup -- the exact hit, nor the writable acquisition after the recursion -- finds it. */
33 return FALSE;
34}
35
37{
38 const dt_dev_pixelpipe_iop_t *detailmask_piece = NULL;
39 for(GList *iter = g_list_first(pipe->nodes); iter; iter = g_list_next(iter))
40 {
41 const dt_dev_pixelpipe_iop_t *candidate = (const dt_dev_pixelpipe_iop_t *)iter->data;
42 if(!candidate) continue;
43 if(candidate->module == target_module) break;
44 if(candidate->enabled && !strcmp(candidate->module->op, "detailmask"))
45 detailmask_piece = candidate;
46 }
47
49 const uint64_t mask_hash = detailmask_piece ? dt_dev_pixelpipe_rawdetail_mask_hash(detailmask_piece)
51
52 if(mask_hash == DT_PIXELPIPE_CACHE_HASH_INVALID) return NULL;
53
54 if(pipe->rawdetail_mask_hash != mask_hash)
55 {
56 // Looked up and referenced at once: nobody may hold the mask when detailmask itself did not run.
57 if(!dt_dev_pixelpipe_cache_ref_entry_by_hash(mask_hash, NULL, NULL)) return NULL;
58
59 dt_dev_clear_rawdetail_mask(mutable_pipe);
60 mutable_pipe->rawdetail_mask_hash = mask_hash;
61 memcpy(&mutable_pipe->rawdetail_mask_roi, &detailmask_piece->roi_out, sizeof(dt_iop_roi_t));
62 }
63
64 void *mask = NULL;
66 return NULL;
67
68 return (float *)mask;
69}
70
72 const dt_iop_module_t *target_module)
73{
74 if(dt_dev_retrieve_rawdetail_mask(pipe, target_module) == NULL) return NULL;
75 gboolean valid = FALSE;
76 const dt_dev_pixelpipe_iop_t *target_piece = NULL;
77 GList *source_iter = NULL;
78 for(GList *iter = g_list_first(pipe->nodes); iter; iter = g_list_next(iter))
79 {
80 const dt_dev_pixelpipe_iop_t *candidate = (dt_dev_pixelpipe_iop_t *)iter->data;
81 if(candidate->module == target_module) target_piece = candidate;
82 if((IS_NULL_PTR(source_iter)) && (!strcmp(candidate->module->op, "detailmask")) && candidate->enabled)
83 {
84 valid = TRUE;
85 source_iter = iter;
86 }
87 }
88
89 if(!valid) return NULL;
90 dt_vprint(DT_DEBUG_MASKS, "[dt_dev_distort_detail_mask] (%ix%i) for module %s\n",
92
93 float *resmask = src;
94 float *inmask = src;
96 if(source_iter)
97 {
98 /* The side-band detail mask is stored in the output geometry of the
99 * hidden `detailmask` stage. Start warping at the next node exactly like
100 * raster masks do, otherwise we would re-apply the source transform to a
101 * buffer that is already expressed in source output coordinates. */
102 for(GList *iter = g_list_next(source_iter); iter; iter = g_list_next(iter))
103 {
104 dt_dev_pixelpipe_iop_t *module = (dt_dev_pixelpipe_iop_t *)iter->data;
105 if(module->enabled
106 && !dt_dev_pixelpipe_activemodule_disables_currentmodule(module->module->dev, module->module))
107 {
108 if(module->module->distort_mask
109 && !(!strcmp(module->module->op, "finalscale")
110 && module->roi_in.width == 0
111 && module->roi_in.height == 0))
112 {
114 (size_t)module->roi_out.width * module->roi_out.height, 0);
115 dt_vprint(DT_DEBUG_MASKS, " %s %ix%i -> %ix%i\n", module->module->op,
116 module->roi_in.width, module->roi_in.height,
117 module->roi_out.width, module->roi_out.height);
118 module->module->distort_mask(module->module, (dt_dev_pixelpipe_t *)pipe, module, inmask, tmp,
119 &module->roi_in, &module->roi_out);
120 resmask = tmp;
121 if(inmask != src) dt_pixelpipe_cache_free_align(inmask);
122 inmask = tmp;
123 current_roi = module->roi_out;
124 }
125 else if(!module->module->distort_mask
126 && (module->roi_in.width != module->roi_out.width
127 || module->roi_in.height != module->roi_out.height
128 || module->roi_in.x != module->roi_out.x
129 || module->roi_in.y != module->roi_out.y))
130 fprintf(stderr, "FIXME: module `%s' changed the roi from %d x %d @ %d / %d to %d x %d | %d / %d but doesn't have "
131 "distort_mask() implemented!\n", module->module->op, module->roi_in.width,
132 module->roi_in.height, module->roi_in.x, module->roi_in.y,
133 module->roi_out.width, module->roi_out.height, module->roi_out.x,
134 module->roi_out.y);
135
136 if(module->module == target_module) break;
137 }
138 }
139 }
140
141 if(!IS_NULL_PTR(target_piece)
142 && (current_roi.scale != target_piece->roi_out.scale
143 || current_roi.width != target_piece->roi_out.width
144 || current_roi.height != target_piece->roi_out.height
145 || current_roi.x != target_piece->roi_out.x
146 || current_roi.y != target_piece->roi_out.y))
147 {
148 /* The cached raw-detail mask is kept at the full-resolution source ROI.
149 * When the downstream walk stops before matching the consumer output ROI,
150 * finish by resampling/cropping once into the consumer geometry, just like
151 * initialscale would do for the pixel buffer. */
153 (size_t)target_piece->roi_out.width * target_piece->roi_out.height, 0);
155 dt_interpolation_resample_roi_1c(itor, tmp, &target_piece->roi_out, inmask, &current_roi);
156 if(inmask != src) dt_pixelpipe_cache_free_align(inmask);
157 inmask = tmp;
158 resmask = tmp;
159 }
160
161 return resmask;
162}
#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
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
@ 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
int dt_dev_pixelpipe_cache_invalidate_hashes(const uint64_t *hashes, const size_t count)
Invalidate cache lines matching an explicit list of hashes.
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.
gboolean dt_dev_pixelpipe_cache_ref_entry_by_hash(const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry)
Resolve and retain an existing cache entry by hash.
#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)
gboolean dt_dev_pixelpipe_rawdetail_mask_check_hit(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const uint64_t output_hash)
Whether a cached output of piece may stand for it, called before that output is looked up.
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