IVGCVSW-863 calculate_max_window..() family takes ValidRegion

Change-Id: I91e39713ffa580e9d2213988ad3517a8a41bf4e8
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/114013
Tested-by: Jenkins <bsgcomp@arm.com>
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
diff --git a/arm_compute/core/Helpers.h b/arm_compute/core/Helpers.h
index 3575fcf..e01e4ba 100644
--- a/arm_compute/core/Helpers.h
+++ b/arm_compute/core/Helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016, 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -361,6 +361,17 @@
 
 /** Calculate the maximum window for a given tensor shape and border setting
  *
+ * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
+ * @param[in] steps        (Optional) Number of elements processed for each step.
+ * @param[in] skip_border  (Optional) If true exclude the border region from the window.
+ * @param[in] border_size  (Optional) Border size.
+ *
+ * @return The maximum window the kernel can be executed on.
+ */
+Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
+
+/** Calculate the maximum window for a given tensor shape and border setting
+ *
  * @param[in] info        Tensor info object defining the shape of the object for which the window is created.
  * @param[in] steps       (Optional) Number of elements processed for each step.
  * @param[in] skip_border (Optional) If true exclude the border region from the window.
@@ -368,18 +379,45 @@
  *
  * @return The maximum window the kernel can be executed on.
  */
-Window calculate_max_window(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
+inline Window calculate_max_window(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize())
+{
+    return calculate_max_window(info.valid_region(), steps, skip_border, border_size);
+}
+
+/** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
+ *
+ * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
+ * @param[in] steps        (Optional) Number of elements processed for each step.
+ * @param[in] skip_border  (Optional) If true exclude the border region from the window.
+ * @param[in] border_size  (Optional) Border size. The border region will be excluded from the window.
+ *
+ * @return The maximum window the kernel can be executed on.
+ */
+Window calculate_max_window_horizontal(const ValidRegion &valid_region, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
 
 /** Calculate the maximum window used by a horizontal kernel for a given tensor shape and border setting
  *
  * @param[in] info        Tensor info object defining the shape of the object for which the window is created.
  * @param[in] steps       (Optional) Number of elements processed for each step.
  * @param[in] skip_border (Optional) If true exclude the border region from the window.
- * @param[in] border_size (Optional) Border size. The border region will be excluded from the window.
+ * @param[in] border_size (Optional) Border size.
  *
  * @return The maximum window the kernel can be executed on.
  */
-Window calculate_max_window_horizontal(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize());
+inline Window calculate_max_window_horizontal(const ITensorInfo &info, const Steps &steps = Steps(), bool skip_border = false, BorderSize border_size = BorderSize())
+{
+    return calculate_max_window_horizontal(info.valid_region(), steps, skip_border, border_size);
+}
+
+/** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
+ *
+ * @param[in] valid_region Valid region object defining the shape of the tensor space for which the window is created.
+ * @param[in] steps        (Optional) Number of elements processed for each step.
+ * @param[in] border_size  (Optional) Border size. The border region will be included in the window.
+ *
+ * @return The maximum window the kernel can be executed on.
+ */
+Window calculate_max_enlarged_window(const ValidRegion &valid_region, const Steps &steps = Steps(), BorderSize border_size = BorderSize());
 
 /** Calculate the maximum window for a given tensor shape and border setting. The window will also includes the border.
  *
@@ -389,7 +427,10 @@
  *
  * @return The maximum window the kernel can be executed on.
  */
-Window calculate_max_enlarged_window(const ITensorInfo &info, const Steps &steps = Steps(), BorderSize border_size = BorderSize());
+inline Window calculate_max_enlarged_window(const ITensorInfo &info, const Steps &steps = Steps(), BorderSize border_size = BorderSize())
+{
+    return calculate_max_enlarged_window(info.valid_region(), steps, border_size);
+}
 
 /** Intersect multiple valid regions.
  *
diff --git a/arm_compute/core/Helpers.inl b/arm_compute/core/Helpers.inl
index 4121fb1..6d0f8b0 100644
--- a/arm_compute/core/Helpers.inl
+++ b/arm_compute/core/Helpers.inl
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016, 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -284,11 +284,14 @@
 
 inline ValidRegion calculate_valid_region_scale(const ITensorInfo &src_info, const TensorShape &dst_shape, InterpolationPolicy policy, BorderSize border_size, bool border_undefined)
 {
-    const auto  wr = static_cast<float>(dst_shape[0]) / static_cast<float>(src_info.tensor_shape()[0]);
-    const auto  hr = static_cast<float>(dst_shape[1]) / static_cast<float>(src_info.tensor_shape()[1]);
-    Coordinates anchor;
-    anchor.set_num_dimensions(src_info.tensor_shape().num_dimensions());
-    TensorShape new_dst_shape(dst_shape);
+    const auto wr = static_cast<float>(dst_shape[0]) / static_cast<float>(src_info.tensor_shape()[0]);
+    const auto hr = static_cast<float>(dst_shape[1]) / static_cast<float>(src_info.tensor_shape()[1]);
+
+    ValidRegion valid_region{ Coordinates(), dst_shape, src_info.tensor_shape().num_dimensions() };
+
+    Coordinates &anchor = valid_region.anchor;
+    TensorShape &shape  = valid_region.shape;
+
     anchor.set(0, (policy == InterpolationPolicy::BILINEAR
                    && border_undefined) ?
                ((static_cast<int>(src_info.valid_region().anchor[0]) + border_size.left + 0.5f) * wr - 0.5f) :
@@ -306,10 +309,10 @@
                         ((static_cast<int>(src_info.valid_region().anchor[1]) + static_cast<int>(src_info.valid_region().shape[1]) - 1) - 1 + 0.5f) * hr - 0.5f :
                         ((static_cast<int>(src_info.valid_region().anchor[1]) + static_cast<int>(src_info.valid_region().shape[1])) + 0.5f) * hr - 0.5f;
 
-    new_dst_shape.set(0, shape_out_x - anchor[0]);
-    new_dst_shape.set(1, shape_out_y - anchor[1]);
+    shape.set(0, shape_out_x - anchor[0]);
+    shape.set(1, shape_out_y - anchor[1]);
 
-    return ValidRegion(std::move(anchor), std::move(new_dst_shape));
+    return valid_region;
 }
 
 inline Coordinates index2coords(const TensorShape &shape, int index)
diff --git a/arm_compute/core/Types.h b/arm_compute/core/Types.h
index 538449b..5402e35 100644
--- a/arm_compute/core/Types.h
+++ b/arm_compute/core/Types.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016, 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -165,9 +165,17 @@
     ValidRegion &operator=(ValidRegion &&) = default;
     ~ValidRegion()                         = default;
 
-    ValidRegion(Coordinates anchor, TensorShape shape)
-        : anchor{ anchor }, shape{ shape }
+    ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
+        : anchor{ an_anchor }, shape{ a_shape }
     {
+        anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
+    }
+
+    ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
+        : anchor{ an_anchor }, shape{ a_shape }
+    {
+        ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
+        anchor.set_num_dimensions(num_dimensions);
     }
 
     /** Return the start of the valid region for the given dimension @p d */