59 template <
typename Scalar>
60 using Vector2 = std::array<Scalar, 2>;
62 template <
unsigned int N,
typename T>
63 using RegularGrid = MishaK::RegularGrid<N, T>;
66 unsigned int left = 0;
67 unsigned int right = 0;
68 unsigned int bottom = 0;
72 unsigned int width()
const {
return left + right; }
73 unsigned int height()
const {
return bottom + top; }
75 template <
typename Scalar>
77 init(
unsigned int width,
unsigned int height,
span<
const std::array<Scalar, 2>> texcoords)
80 Vector2<Scalar> pix_min_corner{
Scalar(0.5) / width,
Scalar(0.5) / height};
81 Vector2<Scalar> pix_max_corner{
Scalar(width - 0.5) / width,
Scalar(height - 0.5) / height};
83 Vector2<Scalar> tex_min_corner{texcoords[0][0], texcoords[0][1]};
84 Vector2<Scalar> tex_max_corner{texcoords[0][0], texcoords[0][1]};
85 for (
size_t i = 0; i < texcoords.size(); i++) {
86 for (
int c = 0; c < 2; c++) {
87 tex_min_corner[c] = std::min<Scalar>(tex_min_corner[c], texcoords[i][c]);
89 for (
int c = 0; c < 2; c++) {
90 tex_max_corner[c] = std::max<Scalar>(tex_max_corner[c], texcoords[i][c]);
93 std::swap(tex_min_corner[1], tex_max_corner[1]);
94 tex_min_corner[1] = 1.0 - tex_min_corner[1];
95 tex_max_corner[1] = 1.0 - tex_max_corner[1];
97 "Texture coordinate bounding box : Min ({}, {}). Max ({}, {}). SafeMin ({}, {}). "
108 padding.left = tex_min_corner[0] < pix_min_corner[0]
109 ? (int)ceil((pix_min_corner[0] - tex_min_corner[0]) * width)
111 padding.bottom = tex_min_corner[1] < pix_min_corner[1]
112 ? (int)ceil((pix_min_corner[1] - tex_min_corner[1]) * height)
115 padding.right = tex_max_corner[0] > pix_max_corner[0]
116 ? (int)ceil((tex_max_corner[0] - pix_max_corner[0]) * width)
118 padding.top = tex_max_corner[1] > pix_max_corner[1]
119 ? (int)ceil((tex_max_corner[1] - pix_max_corner[1]) * height)
124 int new_width = width + padding.left + padding.right;
125 int new_height = height + padding.bottom + padding.top;
127 int padded_width = 8 * (((new_width - 1) / 8) + 1);
128 int padded_height = 8 * (((new_height - 1) / 8) + 1);
129 padding.left += (padded_width - new_width);
130 padding.bottom += (padded_height - new_height);
133 if (padding.width() || padding.height()) {
135 "Padding applied : Left {}. Right {}. Bottom {}. Top {}.",
141 logger().debug(
"No padding required!");
149 template <
typename DataType>
150 void pad(RegularGrid<2, DataType>& im)
const
152 if (!(left || right || bottom || top))
return;
154 unsigned int new_width = im.res(0) + left + right;
155 unsigned int new_height = im.res(1) + bottom + top;
157 RegularGrid<2, DataType> new_im;
158 new_im.resize(new_width, new_height);
159 for (
unsigned int i = 0; i < new_width; i++)
160 for (
unsigned int j = 0; j < new_height; j++) {
162 std::min<int>(std::max<int>(0, (
int)i - (
int)left), im.res(0) - 1);
164 std::min<int>(std::max<int>(0, (
int)j - (
int)bottom), im.res(1) - 1);
165 new_im(i, j) = im(ni, nj);
171 template <
class DataType>
172 void unpad(RegularGrid<2, DataType>& im)
const
174 if (!(left || right || bottom || top))
return;
176 unsigned int output_width = im.res(0) - left - right;
177 unsigned int output_height = im.res(1) - bottom - top;
178 RegularGrid<2, DataType> new_im;
179 new_im.resize(output_width, output_height);
180 for (
unsigned int i = 0; i < output_width; i++) {
181 for (
unsigned int j = 0; j < output_height; j++) {
182 new_im(i, j) = im(left + i, bottom + j);
188 template <
typename Scalar>
189 void pad(
int width,
int height,
span<std::array<Scalar, 2>> texcoords)
const
191 if (!(left || right || bottom || top))
return;
193 int new_width = width + left + right;
194 int new_height = height + bottom + top;
196 for (
size_t i = 0; i < texcoords.size(); i++) {
197 texcoords[i][0] = (texcoords[i][0] * width + (
Scalar)(left)) / new_width;
199 1.0 - ((1.0 - texcoords[i][1]) * height + (
Scalar)(bottom)) / new_height;