32 inline uint8_t delta_bilinear_c1u8(
const uint8_t *pixel_ptr,
size_t stride,
float dx,
float dy)
36 const float dx1 = 1.0f - dx;
37 const float dy1 = 1.0f - dy;
39 const float a00 = *pixel_ptr;
40 const float a01 = *(pixel_ptr + 1);
41 const float a10 = *(pixel_ptr + stride);
42 const float a11 = *(pixel_ptr + stride + 1);
44 const float w1 = dx1 * dy1;
45 const float w2 = dx * dy1;
46 const float w3 = dx1 * dy;
47 const float w4 = dx * dy;
49 return a00 * w1 + a01 * w2 + a10 * w3 + a11 * w4;
52 inline uint8_t pixel_bilinear_c1u8(
const uint8_t *first_pixel_ptr,
size_t stride,
float x,
float y)
59 const float dx = x - xi;
60 const float dy = y - yi;
62 return delta_bilinear_c1u8(first_pixel_ptr + xi + yi * stride, stride, dx, dy);
65 inline uint8_t pixel_bilinear_c1u8_clamp(
const uint8_t *first_pixel_ptr,
size_t stride,
size_t width,
size_t height,
float x,
float y)
69 x = std::max(-1.f, std::min(x, static_cast<float>(width)));
70 y = std::max(-1.f, std::min(y, static_cast<float>(height)));
72 const float xi = std::floor(x);
73 const float yi = std::floor(y);
75 const float dx = x - xi;
76 const float dy = y - yi;
78 return delta_bilinear_c1u8(first_pixel_ptr + static_cast<int32_t>(xi) + static_cast<int32_t>(yi) * stride, stride, dx, dy);
81 inline uint8_t pixel_area_c1u8_clamp(
const uint8_t *first_pixel_ptr,
size_t stride,
size_t width,
size_t height,
float wr,
float hr,
int x,
int y)
86 float in_x = (x + 0.5f) * wr - 0.5f;
87 float in_y = (y + 0.5f) * hr - 0.5f;
90 int x_from = std::floor(x * wr - 0.5f - in_x);
91 int y_from = std::floor(y * hr - 0.5f - in_y);
92 int x_to = std::ceil((x + 1) * wr - 0.5f - in_x);
93 int y_to = std::ceil((y + 1) * hr - 0.5f - in_y);
96 in_x = std::max(-1.f, std::min(in_x, static_cast<float>(width)));
97 in_y = std::max(-1.f, std::min(in_y, static_cast<float>(height)));
100 x_from = ((in_x + x_from) < -1) ? -1 : x_from;
101 y_from = ((in_y + y_from) < -1) ? -1 : y_from;
102 x_to = ((in_x + x_to) > width) ? (width - in_x) : x_to;
103 y_to = ((in_y + y_to) > height) ? (height - in_y) : y_to;
106 const int xi = std::floor(in_x);
107 const int yi = std::floor(in_y);
110 const int x_elements = (x_to - x_from + 1);
111 const int y_elements = (y_to - y_from + 1);
116 for(
int j = yi + y_from, je = yi + y_to; j <= je; ++j)
118 const uint8_t *ptr = first_pixel_ptr + j * stride + xi + x_from;
123 return sum / (x_elements * y_elements);
127 #ifndef DOXYGEN_SKIP_THIS 130 template <
size_t dimension>
131 struct IncrementIterators
133 template <
typename T,
typename... Ts>
134 static void unroll(T &&it, Ts &&... iterators)
136 it.increment(dimension);
137 IncrementIterators<dimension>::unroll<Ts...>(std::forward<Ts>(iterators)...);
140 template <
typename T>
141 static void unroll(T &&it)
143 it.increment(dimension);
148 template <
size_t dim>
149 struct ForEachDimension
151 template <
typename L,
typename... Ts>
152 static void unroll(
const Window &w, Coordinates &
id, L &&lambda_function, Ts &&... iterators)
154 const auto &d = w[dim - 1];
156 for(
auto v = d.start(); v < d.end(); v += d.step(), IncrementIterators < dim - 1 >::unroll(iterators...))
159 ForEachDimension < dim - 1 >::unroll(w,
id, lambda_function, iterators...);
165 struct ForEachDimension<0>
167 template <
typename L,
typename... Ts>
168 static void unroll(
const Window &w, Coordinates &
id, L &&lambda_function, Ts &&... iterators)
174 template <
typename L,
typename... Ts>
180 ForEachDimension<Coordinates::num_max_dimensions>::unroll(w,
id, std::forward<L>(lambda_function), std::forward<Ts>(iterators)...);
184 : _ptr(nullptr), _dims()
192 const TensorInfo *info = tensor->info();
194 const Strides &strides = info->strides_in_bytes();
196 _ptr = tensor->buffer() + info->offset_first_element_in_bytes();
199 for(
unsigned int n = 0; n < info->num_dimensions(); ++n)
201 _dims[n]._stride = win[n].step() * strides[n];
202 std::get<0>(_dims)._dim_start += strides[n] * win[n].start();
208 _dims[n]._dim_start = std::get<0>(_dims)._dim_start;
218 _dims[dimension]._dim_start += _dims[dimension]._stride;
220 for(
unsigned int n = 0; n < dimension; ++n)
222 _dims[n]._dim_start = _dims[dimension]._dim_start;
228 return _dims.at(0)._dim_start;
233 return _ptr + _dims.at(0)._dim_start;
240 _dims[dimension]._dim_start = _dims[dimension + 1]._dim_start;
242 for(
unsigned int n = 0; n < dimension; ++n)
244 _dims[n]._dim_start = _dims[dimension]._dim_start;
void increment(size_t dimension)
Increment the iterator along the specified dimension of the step value associated to the dimension...
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
void execute_window_loop(const Window &w, L &&lambda_function, Ts &&...iterators)
Iterate through the passed window, automatically adjusting the iterators and calling the lambda_funct...
constexpr Iterator()
Default constructor to create an empty iterator.
#define ARM_COMPUTE_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md)
void reset(size_t dimension)
Move the iterator back to the beginning of the specified dimension.
constexpr uint8_t * ptr() const
Return a pointer to the current pixel.
__kernel void accumulate(__global uchar *input_ptr, uint input_stride_x, uint input_step_x, uint input_stride_y, uint input_step_y, uint input_offset_first_element_in_bytes, __global uchar *accu_ptr, uint accu_stride_x, uint accu_step_x, uint accu_stride_y, uint accu_step_y, uint accu_offset_first_element_in_bytes)
This function accumulates an input image into output image.
static constexpr size_t num_max_dimensions
Number of dimensions the tensor has.
constexpr int offset() const
Return the offset in bytes from the first element to the current position of the iterator.