Blender V4.3
imageprocess.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 * SPDX-FileCopyrightText: 2024 Blender Authors
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later */
5
10#include <cmath>
11#include <cstdlib>
12
13#include "MEM_guardedalloc.h"
14
15#include "BLI_task.h"
16#include "BLI_utildefines.h"
17
19#include "IMB_imbuf.hh"
20#include "IMB_imbuf_types.hh"
21
23{
24 size_t size;
25 uchar rt, *cp = ibuf->byte_buffer.data;
26 float rtf, *cpf = ibuf->float_buffer.data;
27
28 if (ibuf->byte_buffer.data) {
29 size = ibuf->x * ibuf->y;
30
31 while (size-- > 0) {
32 rt = cp[0];
33 cp[0] = cp[3];
34 cp[3] = rt;
35 rt = cp[1];
36 cp[1] = cp[2];
37 cp[2] = rt;
38 cp += 4;
39 }
40 }
41
42 if (ibuf->float_buffer.data) {
43 size = ibuf->x * ibuf->y;
44
45 while (size-- > 0) {
46 rtf = cpf[0];
47 cpf[0] = cpf[3];
48 cpf[3] = rtf;
49 rtf = cpf[1];
50 cpf[1] = cpf[2];
51 cpf[2] = rtf;
52 cpf += 4;
53 }
54 }
55}
56
57/* -------------------------------------------------------------------- */
61static void processor_apply_func(TaskPool *__restrict pool, void *taskdata)
62{
63 void (*do_thread)(void *) = (void (*)(void *))BLI_task_pool_user_data(pool);
64 do_thread(taskdata);
65}
66
68 int buffer_lines,
69 int handle_size,
70 void *init_customdata,
71 void(init_handle)(void *handle, int start_line, int tot_line, void *customdata),
72 void *(do_thread)(void *))
73{
74 const int lines_per_task = 64;
75
77
78 void *handles;
79 int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task;
80 int i, start_line;
81
82 task_pool = BLI_task_pool_create(reinterpret_cast<void *>(do_thread), TASK_PRIORITY_HIGH);
83
84 handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles");
85
86 start_line = 0;
87
88 for (i = 0; i < total_tasks; i++) {
89 int lines_per_current_task;
90 void *handle = ((char *)handles) + handle_size * i;
91
92 if (i < total_tasks - 1) {
93 lines_per_current_task = lines_per_task;
94 }
95 else {
96 lines_per_current_task = buffer_lines - start_line;
97 }
98
99 init_handle(handle, start_line, lines_per_current_task, init_customdata);
100
101 BLI_task_pool_push(task_pool, processor_apply_func, handle, false, nullptr);
102
103 start_line += lines_per_task;
104 }
105
106 /* work and wait until tasks are done */
108
109 /* Free memory. */
110 MEM_freeN(handles);
112}
113
118
119static void processor_apply_parallel(void *__restrict userdata,
120 const int scanline,
121 const TaskParallelTLS *__restrict /*tls*/)
122{
123 ScanlineGlobalData *data = static_cast<ScanlineGlobalData *>(userdata);
124 data->do_thread(data->custom_data, scanline);
125}
126
128 ScanlineThreadFunc do_thread,
129 void *custom_data)
130{
131 TaskParallelSettings settings;
132 ScanlineGlobalData data = {};
133 data.do_thread = do_thread;
134 data.custom_data = custom_data;
135
137 BLI_task_parallel_range(0, total_scanlines, &data, processor_apply_parallel, &settings);
138}
139
142/* -------------------------------------------------------------------- */
146void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
147{
148 size_t a = size_t(x) * y;
149 float *fp = rect_float;
150
151 while (a--) {
152 const float mul = 1.0f - fp[3];
153 madd_v3_v3fl(fp, backcol, mul);
154 fp[3] = 1.0f;
155
156 fp += 4;
157 }
158}
159
160void IMB_alpha_under_color_byte(uchar *rect, int x, int y, const float backcol[3])
161{
162 size_t a = size_t(x) * y;
163 uchar *cp = rect;
164
165 while (a--) {
166 if (cp[3] == 255) {
167 /* pass */
168 }
169 else if (cp[3] == 0) {
170 cp[0] = backcol[0] * 255;
171 cp[1] = backcol[1] * 255;
172 cp[2] = backcol[2] * 255;
173 }
174 else {
175 float alpha = cp[3] / 255.0;
176 float mul = 1.0f - alpha;
177
178 cp[0] = (cp[0] * alpha) + mul * backcol[0];
179 cp[1] = (cp[1] * alpha) + mul * backcol[1];
180 cp[2] = (cp[2] * alpha) + mul * backcol[2];
181 }
182
183 cp[3] = 255;
184
185 cp += 4;
186 }
187}
188
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
unsigned char uchar
@ TASK_PRIORITY_HIGH
Definition BLI_task.h:57
void * BLI_task_pool_user_data(TaskPool *pool)
Definition task_pool.cc:516
void BLI_task_pool_work_and_wait(TaskPool *pool)
Definition task_pool.cc:471
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition task_range.cc:99
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
Definition task_pool.cc:394
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition BLI_task.h:230
void BLI_task_pool_free(TaskPool *pool)
Definition task_pool.cc:431
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Definition task_pool.cc:450
void(*)(void *custom_data, int scanline) ScanlineThreadFunc
Definition IMB_imbuf.hh:666
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static void mul(btAlignedObjectArray< T > &items, const Q &value)
TaskPool * task_pool
static void processor_apply_func(TaskPool *__restrict pool, void *taskdata)
void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata, void(init_handle)(void *handle, int start_line, int tot_line, void *customdata), void *(do_thread)(void *))
void IMB_alpha_under_color_byte(uchar *rect, int x, int y, const float backcol[3])
void IMB_processor_apply_threaded_scanlines(int total_scanlines, ScanlineThreadFunc do_thread, void *custom_data)
static void processor_apply_parallel(void *__restrict userdata, const int scanline, const TaskParallelTLS *__restrict)
void IMB_convert_rgba_to_abgr(ImBuf *ibuf)
void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
ScanlineThreadFunc do_thread
ParamHandle ** handles