JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_ImageConvolutionKernel.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
35
39
40//==============================================================================
41float ImageConvolutionKernel::getKernelValue (const int x, const int y) const noexcept
42{
43 if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size))
44 return values [x + y * size];
45
47 return 0;
48}
49
50void ImageConvolutionKernel::setKernelValue (const int x, const int y, const float value) noexcept
51{
52 if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size))
53 {
54 values [x + y * size] = value;
55 }
56 else
57 {
59 }
60}
61
63{
64 for (int i = size * size; --i >= 0;)
65 values[i] = 0;
66}
67
69{
70 double currentTotal = 0.0;
71
72 for (int i = size * size; --i >= 0;)
73 currentTotal += values[i];
74
76}
77
79{
80 for (int i = size * size; --i >= 0;)
81 values[i] *= multiplier;
82}
83
84//==============================================================================
86{
87 const double radiusFactor = -1.0 / (radius * radius * 2);
88 const int centre = size >> 1;
89
90 for (int y = size; --y >= 0;)
91 {
92 for (int x = size; --x >= 0;)
93 {
94 auto cx = x - centre;
95 auto cy = y - centre;
96
97 values [x + y * size] = (float) std::exp (radiusFactor * (cx * cx + cy * cy));
98 }
99 }
100
101 setOverallSum (1.0f);
102}
103
104//==============================================================================
106 const Image& sourceImage,
107 const Rectangle<int>& destinationArea) const
108{
109 if (sourceImage == destImage)
110 {
111 destImage.duplicateIfShared();
112 }
113 else
114 {
115 if (sourceImage.getWidth() != destImage.getWidth()
116 || sourceImage.getHeight() != destImage.getHeight()
117 || sourceImage.getFormat() != destImage.getFormat())
118 {
120 return;
121 }
122 }
123
124 auto area = destinationArea.getIntersection (destImage.getBounds());
125
126 if (area.isEmpty())
127 return;
128
129 auto right = area.getRight();
130 auto bottom = area.getBottom();
131
132 const Image::BitmapData destData (destImage, area.getX(), area.getY(), area.getWidth(), area.getHeight(),
133 Image::BitmapData::writeOnly);
134 uint8* line = destData.data;
135
136 const Image::BitmapData srcData (sourceImage, Image::BitmapData::readOnly);
137
138 if (destData.pixelStride == 4)
139 {
140 for (int y = area.getY(); y < bottom; ++y)
141 {
142 uint8* dest = line;
143 line += destData.lineStride;
144
145 for (int x = area.getX(); x < right; ++x)
146 {
147 float c1 = 0;
148 float c2 = 0;
149 float c3 = 0;
150 float c4 = 0;
151
152 for (int yy = 0; yy < size; ++yy)
153 {
154 const int sy = y + yy - (size >> 1);
155
156 if (sy >= srcData.height)
157 break;
158
159 if (sy >= 0)
160 {
161 int sx = x - (size >> 1);
162 const uint8* src = srcData.getPixelPointer (sx, sy);
163
164 for (int xx = 0; xx < size; ++xx)
165 {
166 if (sx >= srcData.width)
167 break;
168
169 if (sx >= 0)
170 {
171 const float kernelMult = values [xx + yy * size];
172 c1 += kernelMult * *src++;
173 c2 += kernelMult * *src++;
174 c3 += kernelMult * *src++;
175 c4 += kernelMult * *src++;
176 }
177 else
178 {
179 src += 4;
180 }
181
182 ++sx;
183 }
184 }
185 }
186
187 *dest++ = (uint8) jmin (0xff, roundToInt (c1));
188 *dest++ = (uint8) jmin (0xff, roundToInt (c2));
189 *dest++ = (uint8) jmin (0xff, roundToInt (c3));
190 *dest++ = (uint8) jmin (0xff, roundToInt (c4));
191 }
192 }
193 }
194 else if (destData.pixelStride == 3)
195 {
196 for (int y = area.getY(); y < bottom; ++y)
197 {
198 uint8* dest = line;
199 line += destData.lineStride;
200
201 for (int x = area.getX(); x < right; ++x)
202 {
203 float c1 = 0;
204 float c2 = 0;
205 float c3 = 0;
206
207 for (int yy = 0; yy < size; ++yy)
208 {
209 const int sy = y + yy - (size >> 1);
210
211 if (sy >= srcData.height)
212 break;
213
214 if (sy >= 0)
215 {
216 int sx = x - (size >> 1);
217 const uint8* src = srcData.getPixelPointer (sx, sy);
218
219 for (int xx = 0; xx < size; ++xx)
220 {
221 if (sx >= srcData.width)
222 break;
223
224 if (sx >= 0)
225 {
226 const float kernelMult = values [xx + yy * size];
227 c1 += kernelMult * *src++;
228 c2 += kernelMult * *src++;
229 c3 += kernelMult * *src++;
230 }
231 else
232 {
233 src += 3;
234 }
235
236 ++sx;
237 }
238 }
239 }
240
241 *dest++ = (uint8) roundToInt (c1);
242 *dest++ = (uint8) roundToInt (c2);
243 *dest++ = (uint8) roundToInt (c3);
244 }
245 }
246 }
247 else if (destData.pixelStride == 1)
248 {
249 for (int y = area.getY(); y < bottom; ++y)
250 {
251 uint8* dest = line;
252 line += destData.lineStride;
253
254 for (int x = area.getX(); x < right; ++x)
255 {
256 float c1 = 0;
257
258 for (int yy = 0; yy < size; ++yy)
259 {
260 const int sy = y + yy - (size >> 1);
261
262 if (sy >= srcData.height)
263 break;
264
265 if (sy >= 0)
266 {
267 int sx = x - (size >> 1);
268 const uint8* src = srcData.getPixelPointer (sx, sy);
269
270 for (int xx = 0; xx < size; ++xx)
271 {
272 if (sx >= srcData.width)
273 break;
274
275 if (sx >= 0)
276 {
277 const float kernelMult = values [xx + yy * size];
278 c1 += kernelMult * *src++;
279 }
280 else
281 {
282 src += 3;
283 }
284
285 ++sx;
286 }
287 }
288 }
289
290 *dest++ = (uint8) roundToInt (c1);
291 }
292 }
293 }
294}
295
296} // namespace juce
void clear()
Resets all values in the kernel to zero.
void setKernelValue(int x, int y, float value) noexcept
Sets the value of a specific cell in the kernel.
void createGaussianBlur(float blurRadius)
Initialises the kernel for a gaussian blur.
void setOverallSum(float desiredTotalSum)
Rescales all values in the kernel to make the total add up to a fixed value.
float getKernelValue(int x, int y) const noexcept
Returns one of the kernel values.
void rescaleAllValues(float multiplier)
Multiplies all values in the kernel by a value.
ImageConvolutionKernel(int size)
Creates an empty convolution kernel.
void applyToImage(Image &destImage, const Image &sourceImage, const Rectangle< int > &destinationArea) const
Applies the kernel to an image.
Retrieves a section of an image as raw pixel data, so it can be read or written to.
Definition juce_Image.h:310
int pixelStride
The number of bytes between each pixel.
Definition juce_Image.h:355
uint8 * getPixelPointer(int x, int y) const noexcept
Returns a pointer to a pixel in the image.
Definition juce_Image.h:334
int lineStride
The number of bytes between each line.
Definition juce_Image.h:354
uint8 * data
The raw pixel data, packed according to the image's pixel format.
Definition juce_Image.h:351
Holds a fixed-size bitmap.
Definition juce_Image.h:58
int getWidth() const noexcept
Returns the image's width (in pixels).
PixelFormat getFormat() const noexcept
Returns the image's pixel format.
int getHeight() const noexcept
Returns the image's height (in pixels).
Manages a rectangle and allows geometric operations to be performed on it.
T exp(T... args)
#define jassertfalse
This will always cause an assertion failure.
typedef float
JUCE Namespace.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also below a specified upper limit.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
typedef size_t