LMMS
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{
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{
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(),
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
Definition juce_Image.h:310
int pixelStride
Definition juce_Image.h:355
int height
Definition juce_Image.h:356
@ writeOnly
Definition juce_Image.h:315
@ readOnly
Definition juce_Image.h:314
uint8 * getPixelPointer(int x, int y) const noexcept
Definition juce_Image.h:334
int lineStride
Definition juce_Image.h:354
int width
Definition juce_Image.h:356
uint8 * data
Definition juce_Image.h:351
void clear()
Definition juce_ImageConvolutionKernel.cpp:62
const int size
Definition juce_ImageConvolutionKernel.h:107
void setKernelValue(int x, int y, float value) noexcept
Definition juce_ImageConvolutionKernel.cpp:50
void createGaussianBlur(float blurRadius)
Definition juce_ImageConvolutionKernel.cpp:85
void setOverallSum(float desiredTotalSum)
Definition juce_ImageConvolutionKernel.cpp:68
float getKernelValue(int x, int y) const noexcept
Definition juce_ImageConvolutionKernel.cpp:41
void rescaleAllValues(float multiplier)
Definition juce_ImageConvolutionKernel.cpp:78
ImageConvolutionKernel(int size)
Definition juce_ImageConvolutionKernel.cpp:29
~ImageConvolutionKernel()
Definition juce_ImageConvolutionKernel.cpp:36
void applyToImage(Image &destImage, const Image &sourceImage, const Rectangle< int > &destinationArea) const
Definition juce_ImageConvolutionKernel.cpp:105
HeapBlock< float > values
Definition juce_ImageConvolutionKernel.h:106
Definition juce_Image.h:58
int getWidth() const noexcept
Definition juce_Image.cpp:271
PixelFormat getFormat() const noexcept
Definition juce_Image.cpp:274
int getHeight() const noexcept
Definition juce_Image.cpp:272
Rectangle< int > getBounds() const noexcept
Definition juce_Image.cpp:273
void duplicateIfShared()
Definition juce_Image.cpp:288
Definition juce_Rectangle.h:67
Rectangle getIntersection(Rectangle other) const noexcept
Definition juce_Rectangle.h:664
int y
Definition inflate.c:1588
register unsigned i
Definition inflate.c:1575
unsigned x[BMAX+1]
Definition inflate.c:1586
struct @113205115357366127300225113341150224053346037032::@137033172036070230260373056156374243321245367362 right
static void c2(register WDL_FFT_COMPLEX *a)
Definition fft.c:270
static void c4(register WDL_FFT_COMPLEX *a)
Definition fft.c:283
static PuglViewHint int value
Definition pugl.h:1708
#define jassertfalse
Definition carla_juce.cpp:31
constexpr Type jmin(Type a, Type b)
Definition juce_MathsFunctions.h:106
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Definition juce_MathsFunctions.h:279
unsigned char uint8
Definition juce_MathsFunctions.h:37
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465