diff --git a/stb_resample.h b/stb_resample.h index f706b52..a1bbe97 100644 --- a/stb_resample.h +++ b/stb_resample.h @@ -27,8 +27,9 @@ Initial implementation by Jorge L Rodriguez typedef enum { - STBR_FILTER_NEAREST = 1, - STBR_FILTER_LINEAR = 2, + STBR_FILTER_NEAREST = 1, + STBR_FILTER_BILINEAR = 2, + STBR_FILTER_BICUBIC = 3, // A cubic b spline } stbr_filter; typedef enum @@ -212,13 +213,15 @@ static stbr_inline int stbr__max(int a, int b) static float stbr__filter_nearest(float x) { - if (fabs(x) <= 0.5) + x = (float)fabs(x); + + if (x <= 0.5) return 1; else return 0; } -static float stbr__filter_linear(float x) +static float stbr__filter_bilinear(float x) { x = (float)fabs(x); @@ -228,10 +231,25 @@ static float stbr__filter_linear(float x) return 0; } +static float stbr__filter_bicubic(float x) +{ + x = (float)fabs(x); + + float xx = x*x; + + if (x < 1.0f) + return 0.5f * (x * xx) - xx + 0.66666666666f; + else if (x < 2.0f) + return -0.16666666f * (x * xx) + xx - 2 * x + 1.3333333333f; + + return (0.0f); +} + static stbr__filter_info stbr__filter_info_table[] = { - { NULL, 0.0f }, - { stbr__filter_nearest, 0.5f }, - { stbr__filter_linear, 1.0f }, + { NULL, 0.0f }, + { stbr__filter_nearest, 0.5f }, + { stbr__filter_bilinear, 1.0f }, + { stbr__filter_bicubic, 2.0f }, }; stbr_inline static int stbr__use_width_upsampling_noinfo(int output_w, int input_w) diff --git a/tests/resample_test.cpp b/tests/resample_test.cpp index f2568db..0077131 100644 --- a/tests/resample_test.cpp +++ b/tests/resample_test.cpp @@ -48,7 +48,7 @@ int main(int argc, char** argv) int in_w = 512; int in_h = 512; - size_t memory_required = stbr_calculate_memory(in_w, in_h, w*n, out_w, out_h, out_stride, n, STBR_FILTER_LINEAR); + size_t memory_required = stbr_calculate_memory(in_w, in_h, w*n, out_w, out_h, out_stride, n, STBR_FILTER_BICUBIC); void* extra_memory = malloc(memory_required); // Cut out the outside 64 pixels all around to test the stride. @@ -56,7 +56,7 @@ int main(int argc, char** argv) STBR_ASSERT(in_w + border <= w); STBR_ASSERT(in_h + border <= h); - stbr_resize_arbitrary(input_data + w * border * n + border * n, in_w, in_h, w*n, output_data, out_w, out_h, out_stride, n, STBR_TYPE_UINT8, STBR_FILTER_LINEAR, STBR_EDGE_CLAMP, extra_memory, memory_required); + stbr_resize_arbitrary(input_data + w * border * n + border * n, in_w, in_h, w*n, output_data, out_w, out_h, out_stride, n, STBR_TYPE_UINT8, STBR_FILTER_BICUBIC, STBR_EDGE_CLAMP, extra_memory, memory_required); free(extra_memory);