31 int32_t y, int32_t depth, int32_t batch,
32 const Shape &input_shape,
const float *input_data,
35 const int32_t input_width = input_shape.
Dims(2);
38 const int32_t input_x_offset = (x1 - x0) * depth;
39 const int32_t input_y_offset = (y1 - y0) * depth * input_width;
40 const int32_t output_x_offset = depth;
41 const int32_t output_y_offset = depth * output_width;
43 for (
int ch = 0; ch < depth; ch++)
45 const int32_t input_offset =
Offset(input_shape, batch, y0, x0, ch);
47 float x0y0 = input_data[input_offset];
48 float x1y0 = input_data[input_offset + input_x_offset];
49 float x0y1 = input_data[input_offset + input_y_offset];
50 float x1y1 = input_data[input_offset + input_x_offset + input_y_offset];
54 output_data[output_offset] = x0y0;
57 output_data[output_offset + output_x_offset] = (x0y0 + x1y0) / 2;
60 float output = (x0y0 + x0y1) / 2;
61 output_data[output_offset + output_y_offset] = output;
64 output_data[output_offset + output_x_offset + output_y_offset] =
65 (output + ((x1y0 + x1y1) / 2)) / 2;
70 int32_t depth, int32_t output_height, int32_t output_width,
71 const Shape &input_shape,
const float *input_data,
74 for (
int b = 0; b < batches; b++)
76 for (
int y0 = 0, y = 0; y <= output_height - 2; y += 2, y0++)
78 for (
int x0 = 0, x = 0; x <= output_width - 2; x += 2, x0++)
80 int32_t x1 = std::min(x0 + 1, input_width - 1);
81 int32_t y1 = std::min(y0 + 1, input_height - 1);
82 ResizeBilinearKernel2x2(x0, x1, y0, y1, x, y, depth, b, input_shape, input_data,
101 const bool half_pixel_centers, int32_t input_size,
102 float *scaled_value, int32_t *lower_bound,
103 int32_t *upper_bound)
105 if (half_pixel_centers)
107 *scaled_value = (value + 0.5f) * scale - 0.5f;
111 *scaled_value = value * scale;
113 float scaled_value_floor = std::floor(*scaled_value);
114 *lower_bound = std::max(
static_cast<int32_t
>(scaled_value_floor),
static_cast<int32_t
>(0));
115 *upper_bound = std::min(
static_cast<int32_t
>(std::ceil(*scaled_value)), input_size - 1);
119 int32_t depth, int32_t output_height, int32_t output_width,
120 float height_scale,
float width_scale,
const Shape &input_shape,
121 const float *input_data,
float *output_data,
122 const bool half_pixel_centers)
124 memset(output_data, 0, batches * output_height * output_width * depth *
sizeof(
float));
126 int32_t output_offset = 0;
127 for (
int b = 0; b < batches; ++b)
129 for (
int y = 0; y < output_height; ++y)
135 for (
int x = 0; x < output_width; ++x)
141 float *output_ptr = &output_data[output_offset];
144 int32_t input_offset =
Offset(input_shape, b, y0, x0, 0);
145 float scale = (1 - (input_y - y0)) * (1 - (input_x - x0));
146 const float *input_ptr = &input_data[input_offset];
149 input_offset =
Offset(input_shape, b, y0, x1, 0);
150 scale = (1 - (input_y - y0)) * (input_x - x0);
151 input_ptr = &input_data[input_offset];
154 input_offset =
Offset(input_shape, b, y1, x0, 0);
155 scale = (input_y - y0) * (1 - (input_x - x0));
156 input_ptr = &input_data[input_offset];
159 input_offset =
Offset(input_shape, b, y1, x1, 0);
160 scale = (input_y - y0) * (input_x - x0);
161 input_ptr = &input_data[input_offset];
164 output_offset += depth;
172 int32_t input_width, int32_t depth,
173 int32_t output_height, int32_t output_width,
174 float height_scale,
float width_scale,
175 const Shape &input_shape,
const T *input_data,
176 T *output_data,
const bool half_pixel_centers)
178 T *output_ptr = &output_data[0];
179 for (
int b = 0; b < batches; ++b)
181 for (
int y = 0; y < output_height; ++y)
187 for (
int x = 0; x < output_width; ++x)
194 int32_t input_offset[4] = {
195 Offset(input_shape, b, y0, x0, 0),
Offset(input_shape, b, y0, x1, 0),
196 Offset(input_shape, b, y1, x0, 0),
Offset(input_shape, b, y1, x1, 0)};
197 float scale[4] = {(1 - (input_y - y0)) * (1 - (input_x - x0)),
198 (1 - (input_y - y0)) * (input_x - x0),
199 (input_y - y0) * (1 - (input_x - x0)), (input_y - y0) * (input_x - x0)};
201 for (
int d = 0; d < depth; d++)
203 const T *input_ptr = &input_data[d];
204 *output_ptr++ =
static_cast<T
>(
205 input_ptr[input_offset[0]] * scale[0] + input_ptr[input_offset[1]] * scale[1] +
206 input_ptr[input_offset[2]] * scale[2] + input_ptr[input_offset[3]] * scale[3]);
217 int32_t input_height = input_shape.
Dims(1);
218 int32_t input_width = input_shape.
Dims(2);
230 float height_scale =
static_cast<float>(input_height) / params.
output_height;
231 float width_scale =
static_cast<float>(input_width) / params.
output_width;
234 height_scale =
static_cast<float>(input_height - 1) / (params.
output_height - 1);
238 width_scale =
static_cast<float>(input_width - 1) / (params.
output_width - 1);
242 params.
output_width, height_scale, width_scale, input_shape, input_data,
251 int32_t input_height = input_shape.
Dims(1);
252 int32_t input_width = input_shape.
Dims(2);
256 ? (
static_cast<float>(input_height - 1) / (params.
output_height - 1))
260 ? (
static_cast<float>(input_width - 1) / (params.
output_width - 1))
261 : (
static_cast<float>(input_width) / params.
output_width);
263 ResizeBilinearGenericSmallChannel<uint8_t>(
265 height_scale, width_scale, input_shape, input_data, output_data, params.
half_pixel_centers);
269 const bool half_pixel_centers, int32_t input_size,
270 int32_t *scaled_value, int32_t *lower_bound,
271 int32_t *upper_bound)
273 if (half_pixel_centers)
275 *scaled_value = value * scale_10 + scale_10 / 2 - (1 << 9);
279 *scaled_value = value * scale_10;
281 *lower_bound = std::max(*scaled_value / (1 << 10), 0);
282 *upper_bound = std::min(*scaled_value / (1 << 10) + 1, input_size - 1);
286 const Shape &unextended_input_shape,
const int8_t *input_data,
287 const Shape &unextended_output_shape, int8_t *output_data)
293 const Shape input_shape = Shape::ExtendedShape(4, unextended_input_shape);
297 const int32_t input_height = input_shape.
Dims(1);
298 const int32_t input_width = input_shape.
Dims(2);
304 int32_t height_scale_10 = ((1 << 10) * input_height + output_height / 2) / output_height;
305 int32_t width_scale_10 = ((1 << 10) * input_width + output_width / 2) / output_width;
309 ((1 << 10) * (input_height - 1) + (output_height - 1) / 2) / (output_height - 1);
313 width_scale_10 = ((1 << 10) * (input_width - 1) + (output_width - 1) / 2) / (output_width - 1);
316 for (
int b = 0; b < batches; ++b)
318 for (
int y = 0; y < output_height; ++y)
320 int32_t input_y, y0, y1;
323 for (
int x = 0; x < output_width; ++x)
325 int32_t input_x, x0, x1;
328 for (
int c = 0; c < depth; ++c)
330 const int64_t output_20_ll =
331 static_cast<int64_t
>(input_data[
Offset(input_shape, b, y0, x0, c)]) *
332 ((1 << 10) - (input_y - (1 << 10) * y0)) * ((1 << 10) - (input_x - (1 << 10) * x0));
333 const int64_t output_20_lu =
334 static_cast<int64_t
>(input_data[
Offset(input_shape, b, y1, x0, c)]) *
335 (input_y - (1 << 10) * y0) * ((1 << 10) - (input_x - (1 << 10) * x0));
336 const int64_t output_20_rl =
337 static_cast<int64_t
>(input_data[
Offset(input_shape, b, y0, x1, c)]) *
338 ((1 << 10) - (input_y - (1 << 10) * y0)) * (input_x - (1 << 10) * x0);
339 const int64_t output_20_ru =
340 static_cast<int64_t
>(input_data[
Offset(input_shape, b, y1, x1, c)]) *
341 (input_y - (1 << 10) * y0) * (input_x - (1 << 10) * x0);
342 const int64_t output_20 = output_20_ll + output_20_lu + output_20_rl + output_20_ru;
343 const int64_t round = (output_20 > 0) ? (1 << 19) : -(1 << 19);
344 const int8_t interpolation =
static_cast<int8_t
>((output_20 + round) / (1 << 20));
void ResizeBilinear2x2(int32_t batches, int32_t input_height, int32_t input_width, int32_t depth, int32_t output_height, int32_t output_width, const Shape &input_shape, const float *input_data, const Shape &output_shape, float *output_data)
void ResizeBilinearGeneric(int32_t batches, int32_t input_height, int32_t input_width, int32_t depth, int32_t output_height, int32_t output_width, float height_scale, float width_scale, const Shape &input_shape, const float *input_data, float *output_data, const bool half_pixel_centers)
void ResizeBilinearGenericSmallChannel(int32_t batches, int32_t input_height, int32_t input_width, int32_t depth, int32_t output_height, int32_t output_width, float height_scale, float width_scale, const Shape &input_shape, const T *input_data, T *output_data, const bool half_pixel_centers)
void ResizeBilinearKernel2x2(int32_t x0, int32_t x1, int32_t y0, int32_t y1, int32_t x, int32_t y, int32_t depth, int32_t batch, const Shape &input_shape, const float *input_data, const Shape &output_shape, float *output_data)
void ComputeInterpolationValues(const float value, const float scale, const bool half_pixel_centers, int32_t input_size, float *scaled_value, int32_t *lower_bound, int32_t *upper_bound)