Make consistent tests for whether we're doing upsampling or downsampling of width and height. Don't request memory for horizontal buffer or encode buffer if we don't need it.

This commit is contained in:
Jorge Rodriguez 2014-07-24 23:50:14 -07:00
parent 666c025710
commit 27926e78b8

View File

@ -224,6 +224,26 @@ static stbr__filter_info stbr__filter_info_table[] = {
{ stbr__filter_nearest, 0.5f },
};
stbr_inline static int stbr__use_width_upsampling_noinfo(int output_w, int input_w)
{
return output_w > input_w;
}
stbr_inline static int stbr__use_height_upsampling_noinfo(int output_h, int input_h)
{
return output_h > input_h;
}
stbr_inline static int stbr__use_width_upsampling(stbr__info* stbr_info)
{
return stbr__use_width_upsampling_noinfo(stbr_info->output_w, stbr_info->input_w);
}
stbr_inline static int stbr__use_height_upsampling(stbr__info* stbr_info)
{
return stbr__use_height_upsampling_noinfo(stbr_info->output_h, stbr_info->input_h);
}
// This is the maximum number of input samples that can affect an output sample
// with the given filter
stbr_inline static int stbr__get_filter_texel_width(stbr_filter filter)
@ -338,7 +358,7 @@ static void stbr__calculate_horizontal_filters(stbr__info* stbr_info)
int total_contributors = stbr_info->total_horizontal_contributors;
if (stbr_info->output_w > stbr_info->input_w)
if (stbr__use_width_upsampling(stbr_info))
{
float out_pixels_radius = stbr__filter_info_table[stbr_info->filter].support * scale_ratio;
@ -434,7 +454,6 @@ static float* stbr__add_empty_ring_buffer_entry(stbr__info* stbr_info, int n)
static void stbr__resample_horizontal_upsample(stbr__info* stbr_info, int n, float* output_buffer)
{
STBR_UNIMPLEMENTED(stbr_info->output_w < stbr_info->input_w);
int x, k, c;
int output_w = stbr_info->output_w;
int kernel_texel_width = stbr_info->kernel_texel_width;
@ -483,7 +502,7 @@ static void stbr__resample_horizontal_downsample(stbr__info* stbr_info, int n, f
stbr__contributors* horizontal_contributors = stbr_info->horizontal_contributors;
float* horizontal_coefficients = stbr_info->horizontal_coefficients;
STBR_DEBUG_ASSERT(stbr_info->output_w < stbr_info->input_w);
STBR_DEBUG_ASSERT(!stbr__use_width_upsampling(stbr_info));
for (x = 0; x < input_w; x++)
{
@ -527,7 +546,7 @@ static void stbr__decode_and_resample_upsample(stbr__info* stbr_info, int n)
stbr__decode_scanline(stbr_info, n);
// Now resample it into the ring buffer.
if (stbr_info->output_w > stbr_info->input_w)
if (stbr__use_width_upsampling(stbr_info))
stbr__resample_horizontal_upsample(stbr_info, n, stbr__add_empty_ring_buffer_entry(stbr_info, n));
else
stbr__resample_horizontal_downsample(stbr_info, n, stbr__add_empty_ring_buffer_entry(stbr_info, n));
@ -549,7 +568,7 @@ static void stbr__decode_and_resample_downsample(stbr__info* stbr_info, int n)
memset(stbr_info->horizontal_buffer, 0, stbr_info->output_w * stbr_info->channels * sizeof(float));
// Now resample it into the horizontal buffer.
if (stbr_info->output_w > stbr_info->input_w)
if (stbr__use_width_upsampling(stbr_info))
stbr__resample_horizontal_upsample(stbr_info, n, stbr_info->horizontal_buffer);
else
stbr__resample_horizontal_downsample(stbr_info, n, stbr_info->horizontal_buffer);
@ -590,7 +609,7 @@ static void stbr__resample_vertical_upsample(stbr__info* stbr_info, int n, int i
int output_row_index = n * stbr_info->output_stride_bytes;
STBR_DEBUG_ASSERT(stbr_info->output_h > stbr_info->input_h);
STBR_DEBUG_ASSERT(stbr__use_height_upsampling(stbr_info));
STBR_DEBUG_ASSERT(n0 >= in_first_scanline);
STBR_DEBUG_ASSERT(n1 <= in_last_scanline);
@ -644,7 +663,7 @@ static void stbr__resample_vertical_downsample(stbr__info* stbr_info, int n, int
int n0 = vertical_contributors->n0;
int n1 = vertical_contributors->n1;
STBR_DEBUG_ASSERT(stbr_info->output_h < stbr_info->input_h);
STBR_DEBUG_ASSERT(!stbr__use_height_upsampling(stbr_info));
STBR_DEBUG_ASSERT(n0 >= in_first_scanline);
STBR_DEBUG_ASSERT(n1 <= in_last_scanline);
@ -681,7 +700,7 @@ static void stbr__buffer_loop_upsample(stbr__info* stbr_info)
float scale_ratio = (float)stbr_info->output_h / stbr_info->input_h;
float out_scanlines_radius = stbr__filter_info_table[stbr_info->filter].support * scale_ratio;
STBR_DEBUG_ASSERT(stbr_info->output_h > stbr_info->input_h);
STBR_DEBUG_ASSERT(stbr__use_height_upsampling(stbr_info));
for (y = 0; y < stbr_info->output_h; y++)
{
@ -776,7 +795,7 @@ static void stbr__buffer_loop_downsample(stbr__info* stbr_info)
float scale_ratio = (float)stbr_info->output_h / stbr_info->input_h;
float in_pixels_radius = stbr__filter_info_table[stbr_info->filter].support / scale_ratio;
STBR_DEBUG_ASSERT(stbr_info->input_h > stbr_info->output_h);
STBR_DEBUG_ASSERT(!stbr__use_height_upsampling(stbr_info));
for (y = 0; y < stbr_info->input_h; y++)
{
@ -865,9 +884,19 @@ STBRDEF int stbr_resize_arbitrary(const void* input_data, int input_w, int input
stbr_info->horizontal_coefficients = STBR__NEXT_MEMPTR(stbr_info->horizontal_contributors, stbr_info->total_horizontal_contributors * sizeof(stbr__contributors), float);
stbr_info->vertical_coefficients = STBR__NEXT_MEMPTR(stbr_info->horizontal_coefficients, stbr_info->total_coefficients * sizeof(float), float);
stbr_info->decode_buffer = STBR__NEXT_MEMPTR(stbr_info->vertical_coefficients, stbr_info->kernel_texel_width * sizeof(float), float);
stbr_info->horizontal_buffer = STBR__NEXT_MEMPTR(stbr_info->decode_buffer, input_w * channels * sizeof(float), float);
stbr_info->ring_buffer = STBR__NEXT_MEMPTR(stbr_info->horizontal_buffer, output_w * channels * sizeof(float), float);
stbr_info->encode_buffer = STBR__NEXT_MEMPTR(stbr_info->ring_buffer, output_w * channels * sizeof(float) * stbr_info->kernel_texel_width, float);
if (stbr__use_height_upsampling(stbr_info))
{
stbr_info->horizontal_buffer = NULL;
stbr_info->ring_buffer = STBR__NEXT_MEMPTR(stbr_info->decode_buffer, input_w * channels * sizeof(float), float);
stbr_info->encode_buffer = STBR__NEXT_MEMPTR(stbr_info->ring_buffer, output_w * channels * sizeof(float) * stbr_info->kernel_texel_width, float);
}
else
{
stbr_info->horizontal_buffer = STBR__NEXT_MEMPTR(stbr_info->decode_buffer, input_w * channels * sizeof(float), float);
stbr_info->ring_buffer = STBR__NEXT_MEMPTR(stbr_info->horizontal_buffer, output_w * channels * sizeof(float), float);
stbr_info->encode_buffer = NULL;
}
#undef STBR__NEXT_MEMPTR
@ -876,7 +905,7 @@ STBRDEF int stbr_resize_arbitrary(const void* input_data, int input_w, int input
stbr__calculate_horizontal_filters(stbr_info);
if (stbr_info->output_h >= stbr_info->input_h)
if (stbr__use_height_upsampling(stbr_info))
stbr__buffer_loop_upsample(stbr_info);
else
stbr__buffer_loop_downsample(stbr_info);
@ -906,6 +935,16 @@ STBRDEF stbr_size_t stbr_calculate_memory(int input_w, int input_h, int input_st
int ring_buffer_size = output_w * channels * sizeof(float) * stbr__get_filter_texel_width(filter);
int encode_buffer_size = channels * sizeof(float);
if (stbr__use_height_upsampling_noinfo(output_h, input_h))
// The horizontal buffer is for when we're downsampling the height and we
// can't output the result of sampling the decode buffer directly into the
// ring buffers.
horizontal_buffer_size = 0;
else
// The encode buffer is to retain precision in the height upsampling method
// and isn't used when height downsampling.
encode_buffer_size = 0;
return info_size + contributors_size + horizontal_coefficients_size + vertical_coefficients_size + decode_buffer_size + horizontal_buffer_size + ring_buffer_size + encode_buffer_size;
}