mirror of
https://github.com/nothings/stb
synced 2025-01-06 14:52:00 +03:00
Use a carefully shaped trapezoid instead of a box filter to avoid jumps between pixel values.
This commit is contained in:
parent
6922628106
commit
953a637841
@ -139,7 +139,7 @@ STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels
|
||||
typedef enum
|
||||
{
|
||||
STBIR_FILTER_DEFAULT = 0, // use same filter type that easy-to-use API chooses
|
||||
STBIR_FILTER_BOX = 1,
|
||||
STBIR_FILTER_BOX = 1, // Is actually a trapezoid. See https://developer.nvidia.com/content/non-power-two-mipmapping
|
||||
STBIR_FILTER_BILINEAR = 2,
|
||||
STBIR_FILTER_BICUBIC = 3, // A cubic b spline
|
||||
STBIR_FILTER_CATMULLROM = 4,
|
||||
@ -321,6 +321,8 @@ typedef unsigned char stbir__validate_uint32[sizeof(stbir_uint32) == 4 ? 1 : -1]
|
||||
#define STBIR_MAX_CHANNELS 16
|
||||
#endif
|
||||
|
||||
#define STBIR__UNUSED_PARAM(s) s=s;
|
||||
|
||||
// must match stbir_datatype
|
||||
static unsigned char stbir__type_size[] = {
|
||||
1, // STBIR_TYPE_UINT8
|
||||
@ -330,12 +332,13 @@ static unsigned char stbir__type_size[] = {
|
||||
};
|
||||
|
||||
// Kernel function centered at 0
|
||||
typedef float (stbir__kernel_fn)(float x);
|
||||
typedef float (stbir__kernel_fn)(float x, float scale);
|
||||
typedef float (stbir__support_fn)(float scale);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
stbir__kernel_fn* kernel;
|
||||
float support;
|
||||
stbir__support_fn* support;
|
||||
} stbir__filter_info;
|
||||
|
||||
// When upsampling, the contributors are which source pixels contribute.
|
||||
@ -529,18 +532,36 @@ static unsigned char stbir__linear_to_srgb_uchar(float f)
|
||||
return (unsigned char)v + fix;
|
||||
}
|
||||
|
||||
static float stbir__filter_box(float x)
|
||||
static float stbir__filter_trapezoid(float x, float scale)
|
||||
{
|
||||
if (x <= -0.5f)
|
||||
return 0;
|
||||
else if (x > 0.5f)
|
||||
STBIR__DEBUG_ASSERT(scale <= 1);
|
||||
x = (float)fabs(x);
|
||||
|
||||
float halfscale = scale / 2;
|
||||
float t = 0.5f + halfscale;
|
||||
|
||||
if (x >= t)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
{
|
||||
float r = 0.5f - halfscale;
|
||||
if (x <= r)
|
||||
return 1;
|
||||
else
|
||||
return (t - x) / scale;
|
||||
}
|
||||
}
|
||||
|
||||
static float stbir__filter_bilinear(float x)
|
||||
static float stbir__support_trapezoid(float scale)
|
||||
{
|
||||
STBIR__DEBUG_ASSERT(scale <= 1);
|
||||
return 0.5f + scale / 2;
|
||||
}
|
||||
|
||||
static float stbir__filter_bilinear(float x, float s)
|
||||
{
|
||||
STBIR__UNUSED_PARAM(s)
|
||||
|
||||
x = (float)fabs(x);
|
||||
|
||||
if (x <= 1.0f)
|
||||
@ -549,8 +570,10 @@ static float stbir__filter_bilinear(float x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float stbir__filter_bicubic(float x)
|
||||
static float stbir__filter_bicubic(float x, float s)
|
||||
{
|
||||
STBIR__UNUSED_PARAM(s)
|
||||
|
||||
x = (float)fabs(x);
|
||||
|
||||
if (x < 1.0f)
|
||||
@ -561,8 +584,10 @@ static float stbir__filter_bicubic(float x)
|
||||
return (0.0f);
|
||||
}
|
||||
|
||||
static float stbir__filter_catmullrom(float x)
|
||||
static float stbir__filter_catmullrom(float x, float s)
|
||||
{
|
||||
STBIR__UNUSED_PARAM(s)
|
||||
|
||||
x = (float)fabs(x);
|
||||
|
||||
if (x < 1.0f)
|
||||
@ -573,8 +598,10 @@ static float stbir__filter_catmullrom(float x)
|
||||
return (0.0f);
|
||||
}
|
||||
|
||||
static float stbir__filter_mitchell(float x)
|
||||
static float stbir__filter_mitchell(float x, float s)
|
||||
{
|
||||
STBIR__UNUSED_PARAM(s)
|
||||
|
||||
x = (float)fabs(x);
|
||||
|
||||
if (x < 1.0f)
|
||||
@ -585,13 +612,31 @@ static float stbir__filter_mitchell(float x)
|
||||
return (0.0f);
|
||||
}
|
||||
|
||||
static float stbir__support_zero(float s)
|
||||
{
|
||||
STBIR__UNUSED_PARAM(s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float stbir__support_one(float s)
|
||||
{
|
||||
STBIR__UNUSED_PARAM(s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static float stbir__support_two(float s)
|
||||
{
|
||||
STBIR__UNUSED_PARAM(s)
|
||||
return 2;
|
||||
}
|
||||
|
||||
static stbir__filter_info stbir__filter_info_table[] = {
|
||||
{ NULL, 0.0f },
|
||||
{ stbir__filter_box , 0.5f },
|
||||
{ stbir__filter_bilinear, 1.0f },
|
||||
{ stbir__filter_bicubic, 2.0f },
|
||||
{ stbir__filter_catmullrom, 2.0f },
|
||||
{ stbir__filter_mitchell, 2.0f },
|
||||
{ NULL, stbir__support_zero },
|
||||
{ stbir__filter_trapezoid, stbir__support_trapezoid },
|
||||
{ stbir__filter_bilinear, stbir__support_one },
|
||||
{ stbir__filter_bicubic, stbir__support_two },
|
||||
{ stbir__filter_catmullrom, stbir__support_two },
|
||||
{ stbir__filter_mitchell, stbir__support_two },
|
||||
};
|
||||
|
||||
stbir__inline static int stbir__use_upsampling(float ratio)
|
||||
@ -617,9 +662,9 @@ stbir__inline static int stbir__get_filter_pixel_width(stbir_filter filter, floa
|
||||
STBIR_ASSERT(filter < STBIR__ARRAY_SIZE(stbir__filter_info_table));
|
||||
|
||||
if (stbir__use_upsampling(scale))
|
||||
return (int)ceil(stbir__filter_info_table[filter].support * 2);
|
||||
return (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2);
|
||||
else
|
||||
return (int)ceil(stbir__filter_info_table[filter].support * 2 / scale);
|
||||
return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2 / scale);
|
||||
}
|
||||
|
||||
stbir__inline static int stbir__get_filter_pixel_width_horizontal(stbir__info* stbir_info)
|
||||
@ -771,13 +816,13 @@ static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radi
|
||||
*out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5));
|
||||
}
|
||||
|
||||
static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbir_filter filter, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group)
|
||||
static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group)
|
||||
{
|
||||
int i;
|
||||
float total_filter = 0;
|
||||
float filter_scale;
|
||||
|
||||
STBIR__DEBUG_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support * 2)); // Taken directly from stbir__get_filter_pixel_width() which we can't call because we don't know if we're horizontal or vertical.
|
||||
STBIR__DEBUG_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2)); // Taken directly from stbir__get_filter_pixel_width() which we can't call because we don't know if we're horizontal or vertical.
|
||||
|
||||
contributor->n0 = in_first_pixel;
|
||||
contributor->n1 = in_last_pixel;
|
||||
@ -787,7 +832,7 @@ static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbi
|
||||
for (i = 0; i <= in_last_pixel - in_first_pixel; i++)
|
||||
{
|
||||
float in_pixel_center = (float)(i + in_first_pixel) + 0.5f;
|
||||
total_filter += coefficient_group[i] = stbir__filter_info_table[filter].kernel(in_center_of_out - in_pixel_center);
|
||||
total_filter += coefficient_group[i] = stbir__filter_info_table[filter].kernel(in_center_of_out - in_pixel_center, 1 / scale);
|
||||
}
|
||||
|
||||
STBIR__DEBUG_ASSERT(total_filter > 0.9);
|
||||
@ -804,7 +849,7 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st
|
||||
{
|
||||
int i;
|
||||
|
||||
STBIR__DEBUG_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support * 2 / scale_ratio)); // Taken directly from stbir__get_filter_pixel_width() which we can't call because we don't know if we're horizontal or vertical.
|
||||
STBIR__DEBUG_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(scale_ratio) * 2 / scale_ratio)); // Taken directly from stbir__get_filter_pixel_width() which we can't call because we don't know if we're horizontal or vertical.
|
||||
|
||||
contributor->n0 = out_first_pixel;
|
||||
contributor->n1 = out_last_pixel;
|
||||
@ -815,7 +860,7 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st
|
||||
{
|
||||
float out_pixel_center = (float)(i + out_first_pixel) + 0.5f;
|
||||
float x = out_pixel_center - out_center_of_in;
|
||||
coefficient_group[i] = stbir__filter_info_table[filter].kernel(x) * scale_ratio;
|
||||
coefficient_group[i] = stbir__filter_info_table[filter].kernel(x, scale_ratio) * scale_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
@ -873,7 +918,7 @@ static void stbir__calculate_horizontal_filters(stbir__info* stbir_info)
|
||||
|
||||
if (stbir__use_width_upsampling(stbir_info))
|
||||
{
|
||||
float out_pixels_radius = stbir__filter_info_table[stbir_info->horizontal_filter].support * scale_ratio;
|
||||
float out_pixels_radius = stbir__filter_info_table[stbir_info->horizontal_filter].support(1/scale_ratio) * scale_ratio;
|
||||
|
||||
// Looping through out pixels
|
||||
for (n = 0; n < total_contributors; n++)
|
||||
@ -883,12 +928,12 @@ static void stbir__calculate_horizontal_filters(stbir__info* stbir_info)
|
||||
|
||||
stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, stbir_info->horizontal_shift, &in_first_pixel, &in_last_pixel, &in_center_of_out);
|
||||
|
||||
stbir__calculate_coefficients_upsample(stbir_info, stbir_info->horizontal_filter, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(stbir_info, n), stbir__get_coefficient(stbir_info, n, 0));
|
||||
stbir__calculate_coefficients_upsample(stbir_info, stbir_info->horizontal_filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(stbir_info, n), stbir__get_coefficient(stbir_info, n, 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float in_pixels_radius = stbir__filter_info_table[stbir_info->horizontal_filter].support / scale_ratio;
|
||||
float in_pixels_radius = stbir__filter_info_table[stbir_info->horizontal_filter].support(scale_ratio) / scale_ratio;
|
||||
|
||||
// Looping through in pixels
|
||||
for (n = 0; n < total_contributors; n++)
|
||||
@ -1399,7 +1444,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
|
||||
|
||||
int n0,n1, output_row_start;
|
||||
|
||||
stbir__calculate_coefficients_upsample(stbir_info, stbir_info->vertical_filter, in_first_scanline, in_last_scanline, in_center_of_out, vertical_contributors, vertical_coefficients);
|
||||
stbir__calculate_coefficients_upsample(stbir_info, stbir_info->vertical_filter, stbir_info->vertical_scale, in_first_scanline, in_last_scanline, in_center_of_out, vertical_contributors, vertical_coefficients);
|
||||
|
||||
n0 = vertical_contributors->n0;
|
||||
n1 = vertical_contributors->n1;
|
||||
@ -1427,7 +1472,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
|
||||
|
||||
int c;
|
||||
for (c = 0; c < channels; c++)
|
||||
encode_buffer[x*channels + c] += ring_buffer_entry[in_pixel_index + c] * coefficient;
|
||||
encode_buffer[in_pixel_index + c] += ring_buffer_entry[in_pixel_index + c] * coefficient;
|
||||
}
|
||||
}
|
||||
stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode);
|
||||
@ -1486,7 +1531,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
|
||||
{
|
||||
int y;
|
||||
float scale_ratio = stbir_info->vertical_scale;
|
||||
float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support * scale_ratio;
|
||||
float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(1/scale_ratio) * scale_ratio;
|
||||
|
||||
STBIR__DEBUG_ASSERT(stbir__use_height_upsampling(stbir_info));
|
||||
|
||||
@ -1585,7 +1630,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
|
||||
int y;
|
||||
float scale_ratio = stbir_info->vertical_scale;
|
||||
int output_h = stbir_info->output_h;
|
||||
float in_pixels_radius = stbir__filter_info_table[stbir_info->vertical_filter].support / scale_ratio;
|
||||
float in_pixels_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(scale_ratio) / scale_ratio;
|
||||
int pixel_margin = stbir__get_filter_pixel_margin_vertical(stbir_info);
|
||||
int max_y = stbir_info->input_h + pixel_margin;
|
||||
|
||||
|
@ -48,8 +48,10 @@ void stbir_free(void* memory, void* context)
|
||||
return free(memory);
|
||||
}
|
||||
|
||||
//#include <stdio.h>
|
||||
void stbir_progress(float p)
|
||||
{
|
||||
//printf("%f\n", p);
|
||||
STBIR_ASSERT(p >= 0 && p <= 1);
|
||||
}
|
||||
|
||||
@ -373,7 +375,7 @@ void test_subpixel(const char* file, float width_percent, float height_percent,
|
||||
|
||||
unsigned char* output_data = (unsigned char*)malloc(new_w * new_h * n * sizeof(unsigned char));
|
||||
|
||||
stbir_resize_region(input_data, w, h, 0, output_data, new_w, new_h, 0, STBIR_TYPE_UINT8, n, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_CATMULLROM, STBIR_FILTER_CATMULLROM, STBIR_COLORSPACE_SRGB, &g_context, 0, 0, s1, t1);
|
||||
stbir_resize_region(input_data, w, h, 0, output_data, new_w, new_h, 0, STBIR_TYPE_UINT8, n, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_FILTER_CATMULLROM, STBIR_COLORSPACE_SRGB, &g_context, 0, 0, s1, t1);
|
||||
|
||||
stbi_image_free(input_data);
|
||||
|
||||
@ -684,6 +686,72 @@ void test_filters(void)
|
||||
for (j = 0; j < 11 * 11; ++j)
|
||||
STBIR_ASSERT(v == output[j]);
|
||||
}
|
||||
|
||||
{
|
||||
// Now test the trapezoid filter for downsampling.
|
||||
unsigned int input[3 * 1];
|
||||
unsigned int output[2 * 1];
|
||||
|
||||
input[0] = 0;
|
||||
input[1] = 255;
|
||||
input[2] = 127;
|
||||
|
||||
stbir_resize(input, 3, 1, 0, output, 2, 1, 0, STBIR_TYPE_UINT32, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL);
|
||||
|
||||
STBIR_ASSERT(output[0] == (int)round((float)(input[0] * 2 + input[1]) / 3));
|
||||
STBIR_ASSERT(output[1] == (int)round((float)(input[2] * 2 + input[1]) / 3));
|
||||
|
||||
stbir_resize(input, 1, 3, 0, output, 1, 2, 0, STBIR_TYPE_UINT32, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL);
|
||||
|
||||
STBIR_ASSERT(output[0] == (int)round((float)(input[0] * 2 + input[1]) / 3));
|
||||
STBIR_ASSERT(output[1] == (int)round((float)(input[2] * 2 + input[1]) / 3));
|
||||
}
|
||||
|
||||
{
|
||||
// Now test the trapezoid filter for upsampling.
|
||||
unsigned int input[2 * 1];
|
||||
unsigned int output[3 * 1];
|
||||
|
||||
input[0] = 0;
|
||||
input[1] = 255;
|
||||
|
||||
stbir_resize(input, 2, 1, 0, output, 3, 1, 0, STBIR_TYPE_UINT32, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL);
|
||||
|
||||
STBIR_ASSERT(output[0] == input[0]);
|
||||
STBIR_ASSERT(output[1] == (input[0] + input[1]) / 2);
|
||||
STBIR_ASSERT(output[2] == input[1]);
|
||||
|
||||
stbir_resize(input, 1, 2, 0, output, 1, 3, 0, STBIR_TYPE_UINT32, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL);
|
||||
|
||||
STBIR_ASSERT(output[0] == input[0]);
|
||||
STBIR_ASSERT(output[1] == (input[0] + input[1]) / 2);
|
||||
STBIR_ASSERT(output[2] == input[1]);
|
||||
}
|
||||
|
||||
{
|
||||
// Now for some fun.
|
||||
unsigned char input[2 * 1];
|
||||
unsigned char output[127 * 1];
|
||||
|
||||
input[0] = 0;
|
||||
input[1] = 255;
|
||||
|
||||
stbir_resize(input, 2, 1, 0, output, 127, 1, 0, STBIR_TYPE_UINT8, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL);
|
||||
STBIR_ASSERT(output[0] == 0);
|
||||
STBIR_ASSERT(output[127 / 2 - 1] == 0);
|
||||
STBIR_ASSERT(output[127 / 2] == 128);
|
||||
STBIR_ASSERT(output[127 / 2 + 1] == 255);
|
||||
STBIR_ASSERT(output[126] == 255);
|
||||
stbi_write_png("test-output/trapezoid-upsample-horizontal.png", 127, 1, 1, output, 0);
|
||||
|
||||
stbir_resize(input, 1, 2, 0, output, 1, 127, 0, STBIR_TYPE_UINT8, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, STBIR_FILTER_BOX, STBIR_COLORSPACE_LINEAR, NULL);
|
||||
STBIR_ASSERT(output[0] == 0);
|
||||
STBIR_ASSERT(output[127 / 2 - 1] == 0);
|
||||
STBIR_ASSERT(output[127 / 2] == 128);
|
||||
STBIR_ASSERT(output[127 / 2 + 1] == 255);
|
||||
STBIR_ASSERT(output[126] == 255);
|
||||
stbi_write_png("test-output/trapezoid-upsample-vertical.png", 1, 127, 1, output, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -699,52 +767,54 @@ void test_suite(int argc, char **argv)
|
||||
else
|
||||
barbara = "barbara.png";
|
||||
|
||||
#if 1
|
||||
#if 1
|
||||
{
|
||||
float x,y;
|
||||
float x, y;
|
||||
for (x = -1; x < 1; x += 0.05f) {
|
||||
float sums[4] = {0};
|
||||
float sums[5] = { 0 };
|
||||
float o;
|
||||
for (o=-5; o <= 5; ++o) {
|
||||
sums[0] += stbir__filter_mitchell(x+o);
|
||||
sums[1] += stbir__filter_catmullrom(x+o);
|
||||
sums[2] += stbir__filter_bicubic(x+o);
|
||||
sums[3] += stbir__filter_bilinear(x+o);
|
||||
for (o = -5; o <= 5; ++o) {
|
||||
sums[0] += stbir__filter_mitchell(x + o, 1);
|
||||
sums[1] += stbir__filter_catmullrom(x + o, 1);
|
||||
sums[2] += stbir__filter_bicubic(x + o, 1);
|
||||
sums[3] += stbir__filter_bilinear(x + o, 1);
|
||||
sums[4] += stbir__filter_trapezoid(x + o, 0.5f);
|
||||
}
|
||||
for (i=0; i < 4; ++i)
|
||||
for (i = 0; i < 5; ++i)
|
||||
STBIR_ASSERT(sums[i] >= 1.0 - 0.001 && sums[i] <= 1.0 + 0.001);
|
||||
}
|
||||
|
||||
#if 1
|
||||
#if 1
|
||||
for (y = 0.11f; y < 1; y += 0.01f) { // Step
|
||||
for (x = -1; x < 1; x += 0.05f) { // Phase
|
||||
float sums[4] = {0};
|
||||
float sums[5] = { 0 };
|
||||
float o;
|
||||
for (o=-5; o <= 5; o += y) {
|
||||
sums[0] += y * stbir__filter_mitchell(x+o);
|
||||
sums[1] += y * stbir__filter_catmullrom(x+o);
|
||||
sums[2] += y * stbir__filter_bicubic(x+o);
|
||||
sums[3] += y * stbir__filter_bilinear(x+o);
|
||||
for (o = -5; o <= 5; o += y) {
|
||||
sums[0] += y * stbir__filter_mitchell(x + o, 1);
|
||||
sums[1] += y * stbir__filter_catmullrom(x + o, 1);
|
||||
sums[2] += y * stbir__filter_bicubic(x + o, 1);
|
||||
sums[4] += y * stbir__filter_trapezoid(x + o, 0.5f);
|
||||
sums[3] += y * stbir__filter_bilinear(x + o, 1);
|
||||
}
|
||||
for (i=0; i < 3; ++i)
|
||||
for (i = 0; i < 3; ++i)
|
||||
STBIR_ASSERT(sums[i] >= 1.0 - 0.0170 && sums[i] <= 1.0 + 0.0170);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
STBIR_ASSERT(stbir__linear_to_srgb_uchar(stbir__srgb_to_linear(float(i)/255)) == i);
|
||||
STBIR_ASSERT(stbir__linear_to_srgb_uchar(stbir__srgb_to_linear(float(i) / 255)) == i);
|
||||
|
||||
#if 0 // linear_to_srgb_uchar table
|
||||
#if 0 // linear_to_srgb_uchar table
|
||||
for (i=0; i < 256; ++i) {
|
||||
float f = stbir__srgb_to_linear((i+0.5f)/256.0f);
|
||||
printf("%9d, ", (int) ((f) * (1<<28)));
|
||||
if ((i & 7) == 7)
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
test_filters();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user