Skip to content

Commit 222b1e5

Browse files
committed
Expose brightness weights. Add SSE4.2 and AVX2 implementations for brightness.
1 parent 783811c commit 222b1e5

15 files changed

+343
-147
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,8 @@ file(GLOB MAIN_SOURCES
775775
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness.cpp
776776
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness.h
777777
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_Default.cpp
778+
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_SSE42.cpp
779+
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_AVX2.cpp
778780
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_AVX512-VNNI.cpp
779781
Source/Kernels/ImageFilters/RGB32_EuclideanDistance/Kernels_ImageFilter_RGB32_Euclidean.cpp
780782
Source/Kernels/ImageFilters/RGB32_EuclideanDistance/Kernels_ImageFilter_RGB32_Euclidean.h
@@ -2439,6 +2441,7 @@ SET_SOURCE_FILES_PROPERTIES(
24392441
Source/Kernels/AudioStreamConversion/AudioStreamConversion_Core_x86_SSE41.cpp
24402442
Source/Kernels/AbsFFT/Kernels_AbsFFT_Core_x86_SSE41.cpp
24412443
Source/Kernels/ImageFilters/Kernels_ImageFilter_Basic_x64_SSE42.cpp
2444+
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_SSE42.cpp
24422445
Source/Kernels/ImageFilters/RGB32_Range/Kernels_ImageFilter_RGB32_Range_x64_SSE42.cpp
24432446
Source/Kernels/ImageFilters/RGB32_EuclideanDistance/Kernels_ImageFilter_RGB32_Euclidean_x64_SSE42.cpp
24442447
Source/Kernels/ImageScaleBrightness/Kernels_ImageScaleBrightness_x64_SSE41.cpp
@@ -2456,6 +2459,7 @@ if (ARCH_FLAGS_13_Haswell)
24562459
SET_SOURCE_FILES_PROPERTIES(
24572460
Source/Kernels/AbsFFT/Kernels_AbsFFT_Core_x86_AVX2.cpp
24582461
Source/Kernels/ImageFilters/Kernels_ImageFilter_Basic_x64_AVX2.cpp
2462+
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_AVX2.cpp
24592463
Source/Kernels/ImageFilters/RGB32_Range/Kernels_ImageFilter_RGB32_Range_x64_AVX2.cpp
24602464
Source/Kernels/ImageFilters/RGB32_EuclideanDistance/Kernels_ImageFilter_RGB32_Euclidean_x64_AVX2.cpp
24612465
Source/Kernels/ImageScaleBrightness/Kernels_ImageScaleBrightness_x64_AVX2.cpp

SerialPrograms/SerialPrograms.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,9 @@ SOURCES += \
376376
Source/Kernels/ImageFilters/Kernels_ImageFilter_Green_Default.cpp \
377377
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness.cpp \
378378
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_Default.cpp \
379+
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_AVX2.cpp \
379380
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_AVX512-VNNI.cpp \
381+
Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness_x64_SSE42.cpp \
380382
Source/Kernels/ImageFilters/RGB32_EuclideanDistance/Kernels_ImageFilter_RGB32_Euclidean.cpp \
381383
Source/Kernels/ImageFilters/RGB32_EuclideanDistance/Kernels_ImageFilter_RGB32_Euclidean_ARM64_NEON.cpp \
382384
Source/Kernels/ImageFilters/RGB32_EuclideanDistance/Kernels_ImageFilter_RGB32_Euclidean_Default.cpp \

SerialPrograms/Source/CommonTools/Images/ImageFilter.cpp

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -71,43 +71,6 @@ std::vector<std::pair<ImageRGB32, size_t>> filter_rgb32_range(
7171

7272

7373

74-
75-
76-
ImageRGB32 filter_rgb32_euclidean(
77-
const ImageViewRGB32& image,
78-
uint32_t expected, double max_euclidean_distance,
79-
Color replace_with, bool replace_color_within_range
80-
){
81-
ImageRGB32 ret(image.width(), image.height());
82-
Kernels::filter_rgb32_euclidean(
83-
image.data(), image.bytes_per_row(), image.width(), image.height(),
84-
ret.data(), ret.bytes_per_row(),
85-
(uint32_t)replace_with, replace_color_within_range,
86-
expected, max_euclidean_distance
87-
);
88-
return ret;
89-
}
90-
ImageRGB32 filter_rgb32_euclidean(
91-
size_t& pixels_in_range,
92-
const ImageViewRGB32& image,
93-
uint32_t expected, double max_euclidean_distance,
94-
Color replace_with, bool replace_color_within_range
95-
){
96-
ImageRGB32 ret(image.width(), image.height());
97-
pixels_in_range = Kernels::filter_rgb32_euclidean(
98-
image.data(), image.bytes_per_row(), image.width(), image.height(),
99-
ret.data(), ret.bytes_per_row(),
100-
(uint32_t)replace_with, replace_color_within_range,
101-
expected, max_euclidean_distance
102-
);
103-
return ret;
104-
}
105-
106-
107-
108-
109-
110-
11174
ImageRGB32 to_blackwhite_rgb32_range(
11275
const ImageViewRGB32& image,
11376
bool in_range_black,
@@ -163,17 +126,63 @@ std::vector<std::pair<ImageRGB32, size_t>> to_blackwhite_rgb32_range(
163126

164127

165128

129+
130+
131+
132+
133+
134+
135+
ImageRGB32 filter_rgb32_euclidean(
136+
const ImageViewRGB32& image,
137+
uint32_t expected, double max_euclidean_distance,
138+
Color replace_with, bool replace_color_within_range
139+
){
140+
ImageRGB32 ret(image.width(), image.height());
141+
Kernels::filter_rgb32_euclidean(
142+
image.data(), image.bytes_per_row(), image.width(), image.height(),
143+
ret.data(), ret.bytes_per_row(),
144+
(uint32_t)replace_with, replace_color_within_range,
145+
expected, max_euclidean_distance
146+
);
147+
return ret;
148+
}
149+
ImageRGB32 filter_rgb32_euclidean(
150+
size_t& pixels_in_range,
151+
const ImageViewRGB32& image,
152+
uint32_t expected, double max_euclidean_distance,
153+
Color replace_with, bool replace_color_within_range
154+
){
155+
ImageRGB32 ret(image.width(), image.height());
156+
pixels_in_range = Kernels::filter_rgb32_euclidean(
157+
image.data(), image.bytes_per_row(), image.width(), image.height(),
158+
ret.data(), ret.bytes_per_row(),
159+
(uint32_t)replace_with, replace_color_within_range,
160+
expected, max_euclidean_distance
161+
);
162+
return ret;
163+
}
164+
165+
166+
167+
168+
169+
170+
171+
172+
166173
ImageRGB32 to_blackwhite_rgb32_brightness(
167174
const ImageViewRGB32& image,
168175
bool in_range_black,
176+
Kernels::Rgb32BrightnessWeights weights,
169177
uint32_t min_brightness, uint32_t max_brightness
170178
){
171179
ImageRGB32 ret(image.width(), image.height());
172180
Kernels::to_blackwhite_rgb32_brightness(
173181
image.data(), image.bytes_per_row(), image.width(), image.height(),
174182
ret.data(), ret.bytes_per_row(),
175183
in_range_black,
176-
in_range_black, max_brightness
184+
weights,
185+
min_brightness, max_brightness
177186
);
178187
return ret;
179188
}

SerialPrograms/Source/CommonTools/Images/ImageFilter.h

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <cstddef>
1111
#include <vector>
1212
#include "Common/Cpp/Color.h"
13+
#include "Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness.h"
1314

1415
namespace PokemonAutomation{
1516

@@ -35,50 +36,25 @@ ImageRGB32 filter_rgb32_range(
3536
uint32_t mins, uint32_t maxs,
3637
Color replacement_color, bool replace_color_within_range
3738
);
38-
39-
40-
struct FilterRgb32Range{
41-
Color replacement_color;
42-
bool replace_color_within_range;
43-
uint32_t mins;
44-
uint32_t maxs;
45-
};
4639
// Run multiple filters at once. This is more memory efficient than making
4740
// multiple calls to one filter at a time.
4841
// For each filter:
4942
// If `replace_color_within_range` is true, replace the color range [mins, maxs] with the color `replacement_color`.
5043
// If `replace_color_within_range` is false, replace the color outside of the range [mins, maxs] with the color
5144
// `replacement_color`.
5245
// For each filter, return the filtered image and the # of pixels inside the [mins, maxs] range of the filter.
46+
struct FilterRgb32Range{
47+
Color replacement_color;
48+
bool replace_color_within_range;
49+
uint32_t mins;
50+
uint32_t maxs;
51+
};
5352
std::vector<std::pair<ImageRGB32, size_t>> filter_rgb32_range(
5453
const ImageViewRGB32& image,
5554
const std::vector<FilterRgb32Range>& filters
5655
);
5756

5857

59-
// If `replace_color_within_range` is true, replace the colors within (<=) `max_euclidean_distance` of the
60-
// `expected_color` with `replacement_color`.
61-
// If `replace_color_within_range` is false, replace the color outside of the distance with the color `replacement_color`.
62-
ImageRGB32 filter_rgb32_euclidean(
63-
const ImageViewRGB32& image,
64-
uint32_t expected_color, double max_euclidean_distance,
65-
Color replacement_color, bool replace_color_within_range
66-
);
67-
// If `replace_color_within_range` is true, replace the colors within (<=) `max_euclidean_distance` of the
68-
// `expected_color` with `replacement_color`.
69-
// If `replace_color_within_range` is false, replace the color outside of the distance with the color `replacement_color`.
70-
// Returns the # of pixels inside the distance as `pixels_in_range`.
71-
// Note: the alpha channel of `image` and `expected_color` are ignored during computation.
72-
ImageRGB32 filter_rgb32_euclidean(
73-
size_t& pixels_in_range,
74-
const ImageViewRGB32& image,
75-
uint32_t expected_color, double max_euclidean_distance,
76-
Color replacement_color, bool replace_color_within_range
77-
);
78-
79-
80-
81-
8258

8359
// Convert the image to black and white.
8460
// Inside [mins, maxs] is white, otherwise it's black.
@@ -100,9 +76,6 @@ ImageRGB32 to_blackwhite_rgb32_range(
10076
bool in_range_black,
10177
uint32_t mins, uint32_t maxs
10278
);
103-
104-
105-
10679
// Run multiple filters at once. This is more memory efficient than making
10780
// multiple calls to one filter at a time.
10881
// For each filter:
@@ -121,12 +94,48 @@ std::vector<std::pair<ImageRGB32, size_t>> to_blackwhite_rgb32_range(
12194
);
12295

12396

97+
98+
99+
100+
101+
102+
103+
104+
// If `replace_color_within_range` is true, replace the colors within (<=) `max_euclidean_distance` of the
105+
// `expected_color` with `replacement_color`.
106+
// If `replace_color_within_range` is false, replace the color outside of the distance with the color `replacement_color`.
107+
ImageRGB32 filter_rgb32_euclidean(
108+
const ImageViewRGB32& image,
109+
uint32_t expected_color, double max_euclidean_distance,
110+
Color replacement_color, bool replace_color_within_range
111+
);
112+
// If `replace_color_within_range` is true, replace the colors within (<=) `max_euclidean_distance` of the
113+
// `expected_color` with `replacement_color`.
114+
// If `replace_color_within_range` is false, replace the color outside of the distance with the color `replacement_color`.
115+
// Returns the # of pixels inside the distance as `pixels_in_range`.
116+
// Note: the alpha channel of `image` and `expected_color` are ignored during computation.
117+
ImageRGB32 filter_rgb32_euclidean(
118+
size_t& pixels_in_range,
119+
const ImageViewRGB32& image,
120+
uint32_t expected_color, double max_euclidean_distance,
121+
Color replacement_color, bool replace_color_within_range
122+
);
123+
124+
125+
126+
127+
128+
129+
130+
124131
// Similar to "to_blackwhite_rgb32_range()". But instead of checking if each of
125-
// the RGB components are within a range, we check if the sum of them
126-
// (the brightness) is in range.
132+
// the RGB components are within a range, we check if the dot product of the
133+
// components and a set of weights is within a range. By selecting the weights,
134+
// you can pick which components to check the brightness of.
127135
ImageRGB32 to_blackwhite_rgb32_brightness(
128136
const ImageViewRGB32& image,
129137
bool in_range_black,
138+
Kernels::Rgb32BrightnessWeights weights,
130139
uint32_t min_brightness, uint32_t max_brightness
131140
);
132141

SerialPrograms/Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,35 @@ size_t to_blackwhite_rgb32_brightness_x64_AVX512VNNI(
4444
const uint32_t* in, size_t in_bytes_per_row, size_t width, size_t height,
4545
uint32_t* out, size_t out_bytes_per_row,
4646
bool in_range_black,
47+
Rgb32BrightnessWeights weights,
48+
uint32_t min_brightness, uint32_t max_brightness
49+
);
50+
size_t to_blackwhite_rgb32_brightness_x64_AVX2(
51+
const uint32_t* in, size_t in_bytes_per_row, size_t width, size_t height,
52+
uint32_t* out, size_t out_bytes_per_row,
53+
bool in_range_black,
54+
Rgb32BrightnessWeights weights,
55+
uint32_t min_brightness, uint32_t max_brightness
56+
);
57+
size_t to_blackwhite_rgb32_brightness_x64_SSE42(
58+
const uint32_t* in, size_t in_bytes_per_row, size_t width, size_t height,
59+
uint32_t* out, size_t out_bytes_per_row,
60+
bool in_range_black,
61+
Rgb32BrightnessWeights weights,
4762
uint32_t min_brightness, uint32_t max_brightness
4863
);
4964
size_t to_blackwhite_rgb32_brightness_Default(
5065
const uint32_t* in, size_t in_bytes_per_row, size_t width, size_t height,
5166
uint32_t* out, size_t out_bytes_per_row,
5267
bool in_range_black,
68+
Rgb32BrightnessWeights weights,
5369
uint32_t min_brightness, uint32_t max_brightness
5470
);
5571
size_t to_blackwhite_rgb32_brightness(
5672
const uint32_t* in, size_t in_bytes_per_row, size_t width, size_t height,
5773
uint32_t* out, size_t out_bytes_per_row,
5874
bool in_range_black,
75+
Rgb32BrightnessWeights weights,
5976
uint32_t min_brightness, uint32_t max_brightness
6077
){
6178
if (width * height > 0xffffffff){
@@ -67,15 +84,35 @@ size_t to_blackwhite_rgb32_brightness(
6784
in, in_bytes_per_row, width, height,
6885
out, out_bytes_per_row,
6986
in_range_black,
70-
min_brightness, max_brightness
87+
weights, min_brightness, max_brightness
88+
);
89+
}
90+
#endif
91+
#ifdef PA_AutoDispatch_x64_13_Haswell
92+
if (CPU_CAPABILITY_CURRENT.OK_13_Haswell){
93+
return to_blackwhite_rgb32_brightness_x64_AVX2(
94+
in, in_bytes_per_row, width, height,
95+
out, out_bytes_per_row,
96+
in_range_black,
97+
weights, min_brightness, max_brightness
98+
);
99+
}
100+
#endif
101+
#ifdef PA_AutoDispatch_x64_08_Nehalem
102+
if (CPU_CAPABILITY_CURRENT.OK_08_Nehalem){
103+
return to_blackwhite_rgb32_brightness_x64_SSE42(
104+
in, in_bytes_per_row, width, height,
105+
out, out_bytes_per_row,
106+
in_range_black,
107+
weights, min_brightness, max_brightness
71108
);
72109
}
73110
#endif
74111
return to_blackwhite_rgb32_brightness_Default(
75112
in, in_bytes_per_row, width, height,
76113
out, out_bytes_per_row,
77114
in_range_black,
78-
min_brightness, max_brightness
115+
weights, min_brightness, max_brightness
79116
);
80117
}
81118

SerialPrograms/Source/Kernels/ImageFilters/RGB32_Brightness/Kernels_ImageFilter_RGB32_Brightness.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ size_t to_blackwhite_rgb32_brightness(
6161
const uint32_t* in, size_t in_bytes_per_row, size_t width, size_t height,
6262
uint32_t* out, size_t out_bytes_per_row,
6363
bool in_range_black,
64+
Rgb32BrightnessWeights weights,
6465
uint32_t min_brightness, uint32_t max_brightness
6566
);
6667

0 commit comments

Comments
 (0)