Skip to content

Commit

Permalink
NEON binary image filter
Browse files Browse the repository at this point in the history
  • Loading branch information
Gin committed Dec 5, 2023
1 parent 1dcc9c2 commit 2ebd9d9
Show file tree
Hide file tree
Showing 8 changed files with 422 additions and 229 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ void compress_rgb32_to_binary_range(


// Compress (image, bytes_per_row) into a binary_image.
// For each pixel, set to 1 if distance is within the expected value.
// For each pixel, set to 1 if the Euclidean distance of the pixel color to the expected color <= max distance.
void compress_rgb32_to_binary_euclidean(
const uint32_t* image, size_t bytes_per_row,
PackedBinaryMatrix_IB& matrix,
uint32_t expected, double max_euclidean_distance
uint32_t expected_color, double max_euclidean_distance
);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ namespace Kernels{
void filter_by_mask_64x8_arm64_NEON(
const PackedBinaryMatrix_IB& matrix,
uint32_t* image, size_t bytes_per_row,
uint32_t replace_with, bool replace_if_zero
uint32_t replacement_color, bool replace_zero_bits
){
FilterByMask_arm64_NEON filter(replace_with, replace_if_zero);
FilterByMask_arm64_NEON filter(replacement_color, replace_zero_bits);
filter_by_mask(static_cast<const PackedBinaryMatrix_64x8_arm64_NEON&>(matrix).get(), image, bytes_per_row, filter);
}

Expand Down Expand Up @@ -49,12 +49,11 @@ void compress_rgb32_to_binary_euclidean_64x8_arm64_NEON(
PackedBinaryMatrix_IB& matrix,
uint32_t expected, double max_euclidean_distance
){
// TODO:
// Compressor_RgbEuclidean_arm64_NEON compressor(expected, max_euclidean_distance);
// compress_rgb32_to_binary(
// image, bytes_per_row,
// static_cast<PackedBinaryMatrix_64x8_arm64_NEON&>(matrix).get(), compressor
// );
Compressor_RgbEuclidean_arm64_NEON compressor(expected, max_euclidean_distance);
compress_rgb32_to_binary(
image, bytes_per_row,
static_cast<PackedBinaryMatrix_64x8_arm64_NEON&>(matrix).get(), compressor
);
}


Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ class PackedBinaryMatrixCore{
// Word Access. How many words in a column. One word is 8 bytes (aka 64 bits).
size_t word64_height() const{ return m_logical_height; }

// Get (x-th, y-th) word. One word is 16 bytes (aka 64 bits).
// Get (x-th, y-th) word. One word is 8 bytes (aka 64 bits), one row in a tile.
uint64_t word64(size_t x, size_t y) const;
// Get (x-th, y-th) word. One word is 8 bytes (aka 64 bits), one row in a tile.
uint64_t& word64(size_t x, size_t y);

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ class PartialWordAccess_arm64_NEON{
// If `bytes` is 3, then `m_back_mask` is from low bytes to high bytes: [0xFF, 0xFF, 0xFF, ... 0xFF, 0, 0, 0]
m_back_mask = vcgtq_u8(vdupq_n_u8((uint8_t)m_shift), seq_u8x16);

// If `bytes` is 3, then `m_shift_front` is from low bytes to high bytes: [3, 4, 5, 6, 7, ..., 18]
m_shift_front = vaddq_u8(vdupq_n_u8(uint8_t(bytes)), seq_u8x16);
// If `bytes` is 3, then `m_shift_front` is from low bytes to high bytes: [13, 14, 15, 16, 17, ..., 28]
m_shift_front = vaddq_u8(vdupq_n_u8(uint8_t(m_shift)), seq_u8x16);

// IF `bytes` is 3, then `m_shift_back` is from low bytes to hight bytes: [253, 254, 255, 0, 1, 2, 3]
m_shift_back = vsubq_u8(seq_u8x16, vdupq_n_u8((uint8_t)bytes));
// IF `bytes` is 3, then `m_shift_back` is from low bytes to high bytes: [243, 244, 245,... 0, 1, 2]
m_shift_back = vsubq_u8(seq_u8x16, vdupq_n_u8((uint8_t)m_shift));
}

// load() function that does not read past end of buffer
Expand All @@ -50,8 +50,8 @@ class PartialWordAccess_arm64_NEON{
// for each uint8 in the result, ret_u8[i], get the index from `m_shift_front`: m_shift_front[i]
// use the value of m_shift_front[i] as an index to get a value in x:
// ret_u8[i] = x[m_shift_front[i]]
// since `m_shift_front` stores [`bytes`, `bytes+1`, `bytes+2`, ...]
// the resulting operation is to shift the bytes in x to the lower bytes by `bytes` bytes.
// since `m_shift_front` stores [`16-bytes`, `16-bytes+1`, `16-bytes+2`, ...]
// the resulting operation is to shift the bytes in x to the lower bytes by `16-bytes` bytes.
// For the index values >= 16 in m_shift_front[i], `vqtbl1q_u8()` returns 0.
return vqtbl1q_u8(x, m_shift_front);
}
Expand Down
279 changes: 235 additions & 44 deletions SerialPrograms/Source/Tests/Kernels_Tests.cpp

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions SerialPrograms/Source/Tests/Kernels_Tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ int test_kernels_FilterRGB32Euclidean(const ImageViewRGB32& image);

int test_kernels_ToBlackWhiteRGB32Range(const ImageViewRGB32& image);

int test_kernels_FilterByMask(const ImageViewRGB32& image);

int test_kernels_CompressRGB32ToBinaryEuclidean(const ImageViewRGB32& image);

int test_kernels_Waterfill(const ImageViewRGB32& image);


Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/Source/Tests/TestMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ const std::map<std::string, TestFunction> TEST_MAP = {
{"Kernels_FilterRGB32Range", std::bind(image_void_detector_helper, test_kernels_FilterRGB32Range, _1)},
{"Kernels_FilterRGB32Euclidean", std::bind(image_void_detector_helper, test_kernels_FilterRGB32Euclidean, _1)},
{"Kernels_ToBlackWhiteRGB32Range", std::bind(image_void_detector_helper, test_kernels_ToBlackWhiteRGB32Range, _1)},
{"Kernels_FilterByMask", std::bind(image_void_detector_helper, test_kernels_FilterByMask, _1)},
{"Kernels_CompressRGB32ToBinaryEuclidean", std::bind(image_void_detector_helper, test_kernels_CompressRGB32ToBinaryEuclidean, _1)},
{"Kernels_Waterfill", std::bind(image_void_detector_helper, test_kernels_Waterfill, _1)},
{"CommonFramework_BlackBorderDetector", std::bind(image_bool_detector_helper, test_CommonFramework_BlackBorderDetector, _1)},
{"NintendoSwitch_UpdateMenuDetector", std::bind(image_bool_detector_helper, test_NintendoSwitch_UpdateMenuDetector, _1)},
Expand Down

0 comments on commit 2ebd9d9

Please sign in to comment.