Program Listing for File WaveformWebpHighway-inl.h
↰ Return to documentation for file (include\util\function\image\WaveformWebpHighway-inl.h)
#include <algorithm>
#include <cstddef>
#undef HWY_TARGET_INCLUDE
#define HWY_TARGET_INCLUDE "WaveformWebpHighway-inl.h"
#include "hwy/foreach_target.h"
#include <hwy/highway.h>
namespace HWY_NAMESPACE {
HWY_ATTR
void
ComputeWaveformColumnExtremaSIMD(const float *samples,
std::size_t pcm_per_pixel,
std::size_t x_pixels,
float *mins_out,
float *maxs_out)
{
const hwy::HWY_NAMESPACE::ScalableTag<float> tag;
const std::size_t lane_count =
hwy::HWY_NAMESPACE::Lanes(tag);
const auto neg_one = hwy::HWY_NAMESPACE::Set(tag, -1.0f);
const auto pos_one = hwy::HWY_NAMESPACE::Set(tag, 1.0f);
for (std::size_t x = 0; x < x_pixels; ++x) {
const float *column = samples + (x * pcm_per_pixel);
auto min_v = pos_one;
auto max_v = neg_one;
std::size_t i = 0;
for (; i + lane_count <= pcm_per_pixel; i += lane_count) {
auto values = hwy::HWY_NAMESPACE::LoadU(tag, column + i);
values = hwy::HWY_NAMESPACE::Min(
hwy::HWY_NAMESPACE::Max(values, neg_one),
pos_one);
min_v = hwy::HWY_NAMESPACE::Min(min_v, values);
max_v = hwy::HWY_NAMESPACE::Max(max_v, values);
}
float min_sample = hwy::HWY_NAMESPACE::ReduceMin(tag, min_v);
float max_sample = hwy::HWY_NAMESPACE::ReduceMax(tag, max_v);
for (; i < pcm_per_pixel; ++i) {
const float sample = std::clamp(column[i], -1.0f, 1.0f);
min_sample = std::min(min_sample, sample);
max_sample = std::max(max_sample, sample);
}
mins_out[x] = min_sample;
maxs_out[x] = max_sample;
}
}
} // namespace HWY_NAMESPACE