| 39 | { |
| 40 | template <typename T> |
| 41 | SimpleTensor<T> scale_core(const SimpleTensor<T> &in, |
| 42 | float scale_x, |
| 43 | float scale_y, |
| 44 | InterpolationPolicy policy, |
| 45 | BorderMode border_mode, |
| 46 | T constant_border_value, |
| 47 | SamplingPolicy sampling_policy, |
| 48 | bool ceil_policy_scale, |
| 49 | bool align_corners) |
| 50 | { |
| 51 | // Add 1 if ceil_policy_scale is true |
| 52 | const size_t round_value = ceil_policy_scale ? 1U : 0U; |
| 53 | TensorShape shape_scaled(in.shape()); |
| 54 | shape_scaled.set(0, (in.shape()[0] + round_value) * scale_x, /* apply_dim_correction = */ false); |
| 55 | shape_scaled.set(1, (in.shape()[1] + round_value) * scale_y, /* apply_dim_correction = */ false); |
| 56 | SimpleTensor<T> out(shape_scaled, in.data_type()); |
| 57 | |
| 58 | // Compute the ratio between source width/height and destination width/height |
| 59 | const auto wr = arm_compute::scale_utils::calculate_resize_ratio(in.shape()[0], out.shape()[0], align_corners); |
| 60 | const auto hr = arm_compute::scale_utils::calculate_resize_ratio(in.shape()[1], out.shape()[1], align_corners); |
| 61 | |
| 62 | const auto width = static_cast<int>(in.shape().x()); |
| 63 | const auto height = static_cast<int>(in.shape().y()); |
| 64 | |
| 65 | // Determine border size |
| 66 | const int border_size = (border_mode == BorderMode::UNDEFINED) ? 0 : 1; |
| 67 | |
| 68 | // Area interpolation behaves as Nearest Neighbour in case of up-sampling |
| 69 | if (policy == InterpolationPolicy::AREA && wr <= 1.f && hr <= 1.f) |
| 70 | { |
| 71 | policy = InterpolationPolicy::NEAREST_NEIGHBOR; |
| 72 | } |
| 73 | |
| 74 | const uint32_t num_elements = out.num_elements(); |
| 75 | for (uint32_t element_idx = 0, count = 0; element_idx < num_elements; ++element_idx, ++count) |
| 76 | { |
| 77 | Coordinates id = index2coord(out.shape(), element_idx); |
| 78 | int idx = id.x(); |
| 79 | int idy = id.y(); |
| 80 | float x_src = 0; |
| 81 | float y_src = 0; |
| 82 | |
| 83 | switch (policy) |
| 84 | { |
| 85 | case InterpolationPolicy::NEAREST_NEIGHBOR: |
| 86 | { |
| 87 | switch (sampling_policy) |
| 88 | { |
| 89 | case SamplingPolicy::TOP_LEFT: |
| 90 | x_src = align_corners ? arm_compute::utils::rounding::round_half_away_from_zero(idx * wr) |
| 91 | : std::floor(idx * wr); |
| 92 | y_src = align_corners ? arm_compute::utils::rounding::round_half_away_from_zero(idy * hr) |
| 93 | : std::floor(idy * hr); |
| 94 | break; |
| 95 | case SamplingPolicy::CENTER: |
| 96 | //Calculate the source coords without -0.5f is equivalent to round the x_scr/y_src coords |
| 97 | x_src = (idx + 0.5f) * wr; |
| 98 | y_src = (idy + 0.5f) * hr; |
nothing calls this directly
no test coverage detected