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
30 : values ((size_t) (sizeToUse * sizeToUse)),
31 size (sizeToUse)
32{
33 clear();
34}
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
68void ImageConvolutionKernel::setOverallSum (const float desiredTotalSum)
69{
70 double currentTotal = 0.0;
71
72 for (int i = size * size; --i >= 0;)
73 currentTotal += values[i];
74
75 rescaleAllValues ((float) (desiredTotalSum / currentTotal));
76}
77
78void ImageConvolutionKernel::rescaleAllValues (const float multiplier)
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).
Rectangle< int > getBounds() const noexcept
Returns a rectangle with the same size as this image.
void duplicateIfShared()
Makes sure that no other Image objects share the same underlying data as this one.
Manages a rectangle and allows geometric operations to be performed on it.
Rectangle getIntersection(Rectangle other) const noexcept
Returns the region that is the overlap between this and another rectangle.
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.
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