Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
basebuffer.c
Go to the documentation of this file.
1/*
2 This file is part of Ansel.
3 Copyright (C) 2026 Guillaume Stutin.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include "common/darktable.h"
24#include "common/imagebuf.h"
25#include "develop/develop.h"
26#include "develop/imageop.h"
28#include "iop/iop_api.h"
29
30#include <string.h>
31
33
38
40
41const char *name()
42{
43 return _("base buffer");
44}
45
47{
49}
50
55
57{
58 return pipe->dev->image_storage.dsc.cst;
59}
60
61// Full-size RAW in and out
63 const dt_iop_roi_t *const roi_out, dt_iop_roi_t *roi_in)
64{
65 *roi_in = (dt_iop_roi_t){ 0, 0, pipe->iwidth, pipe->iheight, 1.f };
66}
67
69 dt_iop_roi_t *roi_out, const dt_iop_roi_t *const roi_in)
70{
71 *roi_out = (dt_iop_roi_t){ 0, 0, pipe->iwidth, pipe->iheight, 1.f };
72}
73
74
77{
78 memcpy(dsc, &pipe->dev->image_storage.dsc, sizeof(dt_iop_buffer_dsc_t));
79}
80
81
84{
85 memcpy(dsc, &pipe->dev->image_storage.dsc, sizeof(dt_iop_buffer_dsc_t));
86}
87
88
91 const void *const ivoid, void *const ovoid)
92{
93 const dt_iop_roi_t *const roi_out = &piece->roi_out;
95
97
98 // Catch out-of-bounds here because roi_in -> roi_out conversions
99 // use float scaling that may not always respect initial size.
100
101 // Crop rectangle offset. roi_in is always the full sensor buffer here (modify_roi_in()
102 // always requests it whole, so basebuffer can crop any region from it) : the region
103 // actually requested downstream lives in roi_out.
104 const size_t x = MAX(roi_out->x, 0);
105 const size_t y = MAX(roi_out->y, 0);
106
107 // Crop rectangle size, and stride of the full source buffer we are cropping from
108 const size_t in_width = MIN((size_t)roi_out->width, pipe->iwidth - x);
109 const size_t in_height = MIN((size_t)roi_out->height, pipe->iheight - y);
110 const size_t in_stride = pipe->iwidth * piece->dsc_in.bpp;
111 const size_t out_stride = roi_out->width * piece->dsc_out.bpp;
112 const size_t row_bytes = in_width * piece->dsc_in.bpp;
113
114 // Crop offset translated in memory sizes
115 const size_t y_offset = y * in_stride;
116 const size_t x_offset = x * piece->dsc_in.bpp;
117
118 /* This stage copies the immutable mipmap-cache payload into the pixelpipe cacheline that will
119 * be consumed by the first real processing stage. Keeping the source copy local here makes the
120 * cache ownership and lifetime visible in the recursion instead of in a hidden bootstrap path. */
121 const void *const restrict input = buf.buf;
122
124 for(size_t j = 0; j < in_height; j++)
125 memcpy(ovoid + j * out_stride, input + x_offset + y_offset + j * in_stride, MIN(row_bytes, out_stride));
126
128
129 return 0;
130}
131
132#ifdef HAVE_OPENCL
133int 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)
134{
135 const dt_iop_roi_t *const roi_out = &piece->roi_out;
137
139
140 // Catch out-of-bounds here because roi_in -> roi_out conversions
141 // use float scaling that may not always respect initial size.
142
143 // Crop rectangle offset. roi_in is always the full sensor buffer here (modify_roi_in()
144 // always requests it whole, so basebuffer can crop any region from it) : the region
145 // actually requested downstream lives in roi_out.
146 const size_t x = MAX(roi_out->x, 0);
147 const size_t y = MAX(roi_out->y, 0);
148
149 // Stride of the full source buffer we are cropping from
150 const size_t in_stride = pipe->iwidth * piece->dsc_in.bpp;
151
152 // Crop offset translated in memory sizes
153 const size_t y_offset = y * in_stride;
154 const size_t x_offset = x * piece->dsc_in.bpp;
155
156 /* This stage copies the immutable mipmap-cache payload into the pixelpipe cacheline that will
157 * be consumed by the first real processing stage. Keeping the source copy local here makes the
158 * cache ownership and lifetime visible in the recursion instead of in a hidden bootstrap path. */
159 const void *const restrict input = buf.buf;
160
161 // dev_out is a fresh, roi_out-sized device buffer: the write always starts at its own origin.
162 // The crop offset only applies to where we start reading from the host-side full buffer above.
163 size_t origin[] = { 0, 0, 0 };
164 size_t region[] = { MIN((size_t)roi_out->width, pipe->iwidth - x), MIN((size_t)roi_out->height, pipe->iheight - y), 1 };
165
166 int err = dt_opencl_write_host_to_device_raw(pipe->devid, input + x_offset + y_offset, dev_out, origin,
167 region, in_stride, CL_TRUE);
168
169
171
172 return err == CL_SUCCESS;
173}
174#endif
175
176
182
184{
185 dt_free_align(piece->data);
186 piece->data = NULL;
187}
188
190{
191 self->params = calloc(1, sizeof(dt_iop_basebuffer_params_t));
192 self->default_params = calloc(1, sizeof(dt_iop_basebuffer_params_t));
193 self->default_enabled = 1;
194 self->hide_enable_button = 1;
196 self->gui_data = NULL;
197}
198
200{
201 dt_free(self->params);
202 dt_free(self->default_params);
203}
204
205// clang-format off
206// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
207// vim: shiftwidth=2 expandtab tabstop=2 cindent
208// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
209// clang-format on
void modify_roi_out(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_roi_t *roi_out, const dt_iop_roi_t *const roi_in)
Definition basebuffer.c:68
int default_group()
Definition basebuffer.c:46
__DT_CLONE_TARGETS__ int process(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 basebuffer.c:90
void modify_roi_in(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out, dt_iop_roi_t *roi_in)
Definition basebuffer.c:62
const char * name()
Definition basebuffer.c:41
void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition basebuffer.c:75
void cleanup_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition basebuffer.c:183
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Definition basebuffer.c:56
void input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
Definition basebuffer.c:82
int flags()
Definition basebuffer.c:51
void init(dt_iop_module_t *self)
Definition basebuffer.c:189
void init_pipe(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Definition basebuffer.c:177
dt_iop_basebuffer_params_t dt_iop_basebuffer_data_t
Definition basebuffer.c:39
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 basebuffer.c:133
void cleanup(dt_iop_module_t *self)
Definition basebuffer.c:199
darktable_t darktable
Definition darktable.c:183
#define dt_free_align(ptr)
Definition darktable.h:503
static void * dt_calloc_align(size_t size)
Definition darktable.h:510
#define dt_free(ptr)
Definition darktable.h:478
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
Definition darktable.h:151
#define __DT_CLONE_TARGETS__
Definition darktable.h:379
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:270
@ IOP_FLAGS_HIDDEN
Definition imageop.h:200
@ IOP_FLAGS_TAKE_NO_INPUT
Definition imageop.h:206
@ IOP_FLAGS_UNSAFE_COPY
Definition imageop.h:207
@ IOP_FLAGS_ONE_INSTANCE
Definition imageop.h:202
@ IOP_FLAGS_CPU_WRITES_OPENCL
Definition imageop.h:210
@ IOP_FLAGS_NO_HISTORY_STACK
Definition imageop.h:204
@ IOP_GROUP_TECHNICAL
Definition imageop.h:173
void *const ovoid
static const float x
#define dt_mipmap_cache_get(A, B, C, D, E, F)
@ DT_MIPMAP_BLOCKING
#define dt_mipmap_cache_release(A, B)
int dt_opencl_write_host_to_device_raw(const int devid, const void *host, void *device, const size_t *origin, const size_t *region, const int rowpitch, const int blocking)
Definition opencl.c:2277
struct dt_mipmap_cache_t * mipmap_cache
Definition darktable.h:804
dt_iop_buffer_dsc_t dsc_out
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_mipmap_size_t size
struct dt_develop_t * dev
dt_image_t image_storage
Definition develop.h:259
dt_iop_buffer_dsc_t dsc
Definition image.h:337
int32_t hide_enable_button
Definition imageop.h:292
dt_iop_params_t * default_params
Definition imageop.h:344
dt_iop_gui_data_t * gui_data
Definition imageop.h:348
gboolean default_enabled
Definition imageop.h:340
int32_t params_size
Definition imageop.h:346
dt_iop_params_t * params
Definition imageop.h:344
Region of interest passed through the pixelpipe.
Definition imageop.h:72
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29