diff --git a/stb_image_resize.h b/stb_image_resize.h index 6e6dca3..cc3b697 100644 --- a/stb_image_resize.h +++ b/stb_image_resize.h @@ -793,8 +793,7 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st } } -#ifdef STBIR_DEBUG -static void stbir__check_downsample_coefficients(stbir__info* stbir_info) +static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info) { int i; for (i = 0; i < stbir_info->output_w; i++) @@ -813,10 +812,19 @@ static void stbir__check_downsample_coefficients(stbir__info* stbir_info) } STBIR__DEBUG_ASSERT(total > 0.9f); - STBIR__DEBUG_ASSERT(total <= 1.0f + 1.0f / (pow(2.0f, 8.0f * stbir__type_size[stbir_info->type]) - 1)); + STBIR__DEBUG_ASSERT(total < 1.1f); + + float scale = 1 / total; + + for (j = 0; j < stbir__get_horizontal_contributors(stbir_info); j++) + { + if (i >= stbir_info->horizontal_contributors[j].n0 && i <= stbir_info->horizontal_contributors[j].n1) + *stbir__get_coefficient(stbir_info, j, i - stbir_info->horizontal_contributors[j].n0) *= scale; + else if (i < stbir_info->horizontal_contributors[j].n0) + break; + } } } -#endif // Each scan line uses the same kernel values so we should calculate the kernel // values once and then we can use them for every scan line. @@ -858,9 +866,7 @@ static void stbir__calculate_horizontal_filters(stbir__info* stbir_info) stbir__calculate_coefficients_downsample(stbir_info, stbir_info->horizontal_filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(stbir_info, n), stbir__get_coefficient(stbir_info, n, 0)); } -#ifdef STBIR_DEBUG - stbir__check_downsample_coefficients(stbir_info); -#endif + stbir__normalize_downsample_coefficients(stbir_info); } } diff --git a/tests/resample_test.cpp b/tests/resample_test.cpp index de0f94b..02bb92e 100644 --- a/tests/resample_test.cpp +++ b/tests/resample_test.cpp @@ -631,6 +631,22 @@ void test_filters(void) verify_filter_normalized(STBIR_FILTER_BICUBIC, 1, value); verify_filter_normalized(STBIR_FILTER_CATMULLROM, 1, value); verify_filter_normalized(STBIR_FILTER_MITCHELL, 1, value); + + { + // This test is designed to produce coefficients that are very badly denormalized. + int v = 556; + + unsigned int input[100 * 100]; + unsigned int output[11 * 11]; + + for (j = 0; j < 100 * 100; ++j) + input[j] = v; + + stbir_resize(input, 100, 100, 0, output, 11, 11, 0, STBIR_TYPE_UINT32, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BILINEAR, STBIR_FILTER_BILINEAR, STBIR_COLORSPACE_LINEAR, NULL); + + for (j = 0; j < 11 * 11; ++j) + STBIR_ASSERT(v == output[j]); + } } @@ -663,8 +679,8 @@ void test_suite(int argc, char **argv) } #if 1 - for (y = 0.11f; y < 1; y += 0.01f) { - for (x = -1; x < 1; x += 0.05f) { + for (y = 0.11f; y < 1; y += 0.01f) { // Step + for (x = -1; x < 1; x += 0.05f) { // Phase float sums[4] = {0}; float o; for (o=-5; o <= 5; o += y) {