Rearrange the algebra on two of the filters to avoid repeating decimals which cause precision loss. Use int32 to test filters because it's more accurate.

pull/43/head
Jorge Rodriguez 2014-09-09 14:10:14 -07:00
parent ca241daefa
commit 43fbc1d5e3
2 changed files with 35 additions and 32 deletions

View File

@ -528,9 +528,9 @@ static float stbir__filter_bicubic(float x)
x = (float)fabs(x); x = (float)fabs(x);
if (x < 1.0f) if (x < 1.0f)
return 0.66666666666f + x*x*(0.5f*x - 1); return (4 + x*x*(3*x - 6))/6;
else if (x < 2.0f) else if (x < 2.0f)
return 1.3333333333f + x*(-2 + x*(1 - 0.16666666f * x)); return (8 + x*(-12 + x*(6 - x)))/6;
return (0.0f); return (0.0f);
} }
@ -552,9 +552,9 @@ static float stbir__filter_mitchell(float x)
x = (float)fabs(x); x = (float)fabs(x);
if (x < 1.0f) if (x < 1.0f)
return 0.8888888888f + x*x*(1.1666666666666f * x - 2.0f); return (16 + x*x*(21 * x - 36))/18;
else if (x < 2.0f) else if (x < 2.0f)
return 1.777777777777f + x*(-3.3333333333f + x*(2 - 0.3888888888888f*x)); return (32 + x*(-60 + x*(36 - 7*x)))/18;
return (0.0f); return (0.0f);
} }

View File

@ -530,6 +530,7 @@ void test_subpixel_4()
STBIR_ASSERT(memcmp(image, output, 8 * 8) == 0); STBIR_ASSERT(memcmp(image, output, 8 * 8) == 0);
} }
static unsigned int image88_int[8][8];
static unsigned char image88 [8][8]; static unsigned char image88 [8][8];
static unsigned char output88[8][8]; static unsigned char output88[8][8];
static unsigned char output44[4][4]; static unsigned char output44[4][4];
@ -566,16 +567,12 @@ void verify_box(void)
STBIR_ASSERT(output11[0][0] == ((t+32)>>6)); STBIR_ASSERT(output11[0][0] == ((t+32)>>6));
} }
void verify_filter_normalized(stbir_filter filter, unsigned char* output, int output_size) void verify_filter_normalized(stbir_filter filter, int output_size, int value)
{ {
int value = 64;
int i, j; int i, j;
for (j = 0; j < 8; ++j) unsigned int output[64];
for (i = 0; i < 8; ++i)
image88[j][i] = value;
stbir_resize_uint8_generic(image88[0], 8, 8, 0, output, output_size, output_size, 0, 1, -1, 0, STBIR_EDGE_CLAMP, filter, STBIR_COLORSPACE_LINEAR, NULL); stbir_resize(image88_int[0], 8, 8, 0, output, output_size, output_size, 0, STBIR_TYPE_UINT32, 1, STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, filter, filter, STBIR_COLORSPACE_LINEAR, NULL);
for (j = 0; j < output_size; ++j) for (j = 0; j < output_size; ++j)
for (i = 0; i < output_size; ++i) for (i = 0; i < output_size; ++i)
@ -605,29 +602,35 @@ void test_filters(void)
image88[j][i] = i&2 ? 255 : 0; image88[j][i] = i&2 ? 255 : 0;
verify_box(); verify_box();
verify_filter_normalized(STBIR_FILTER_BOX, &output88[0][0], 8); int value = 64;
verify_filter_normalized(STBIR_FILTER_BILINEAR, &output88[0][0], 8);
verify_filter_normalized(STBIR_FILTER_BICUBIC, &output88[0][0], 8);
verify_filter_normalized(STBIR_FILTER_CATMULLROM, &output88[0][0], 8);
verify_filter_normalized(STBIR_FILTER_MITCHELL, &output88[0][0], 8);
verify_filter_normalized(STBIR_FILTER_BOX, &output44[0][0], 4); for (j = 0; j < 8; ++j)
verify_filter_normalized(STBIR_FILTER_BILINEAR, &output44[0][0], 4); for (i = 0; i < 8; ++i)
verify_filter_normalized(STBIR_FILTER_BICUBIC, &output44[0][0], 4); image88_int[j][i] = value;
verify_filter_normalized(STBIR_FILTER_CATMULLROM, &output44[0][0], 4);
verify_filter_normalized(STBIR_FILTER_MITCHELL, &output44[0][0], 4);
verify_filter_normalized(STBIR_FILTER_BOX, &output22[0][0], 2); verify_filter_normalized(STBIR_FILTER_BOX, 8, value);
verify_filter_normalized(STBIR_FILTER_BILINEAR, &output22[0][0], 2); verify_filter_normalized(STBIR_FILTER_BILINEAR, 8, value);
verify_filter_normalized(STBIR_FILTER_BICUBIC, &output22[0][0], 2); verify_filter_normalized(STBIR_FILTER_BICUBIC, 8, value);
verify_filter_normalized(STBIR_FILTER_CATMULLROM, &output22[0][0], 2); verify_filter_normalized(STBIR_FILTER_CATMULLROM, 8, value);
verify_filter_normalized(STBIR_FILTER_MITCHELL, &output22[0][0], 2); verify_filter_normalized(STBIR_FILTER_MITCHELL, 8, value);
verify_filter_normalized(STBIR_FILTER_BOX, &output11[0][0], 1); verify_filter_normalized(STBIR_FILTER_BOX, 4, value);
verify_filter_normalized(STBIR_FILTER_BILINEAR, &output11[0][0], 1); verify_filter_normalized(STBIR_FILTER_BILINEAR, 4, value);
verify_filter_normalized(STBIR_FILTER_BICUBIC, &output11[0][0], 1); verify_filter_normalized(STBIR_FILTER_BICUBIC, 4, value);
verify_filter_normalized(STBIR_FILTER_CATMULLROM, &output11[0][0], 1); verify_filter_normalized(STBIR_FILTER_CATMULLROM, 4, value);
verify_filter_normalized(STBIR_FILTER_MITCHELL, &output11[0][0], 1); verify_filter_normalized(STBIR_FILTER_MITCHELL, 4, value);
verify_filter_normalized(STBIR_FILTER_BOX, 2, value);
verify_filter_normalized(STBIR_FILTER_BILINEAR, 2, value);
verify_filter_normalized(STBIR_FILTER_BICUBIC, 2, value);
verify_filter_normalized(STBIR_FILTER_CATMULLROM, 2, value);
verify_filter_normalized(STBIR_FILTER_MITCHELL, 2, value);
verify_filter_normalized(STBIR_FILTER_BOX, 1, value);
verify_filter_normalized(STBIR_FILTER_BILINEAR, 1, value);
verify_filter_normalized(STBIR_FILTER_BICUBIC, 1, value);
verify_filter_normalized(STBIR_FILTER_CATMULLROM, 1, value);
verify_filter_normalized(STBIR_FILTER_MITCHELL, 1, value);
} }
@ -671,7 +674,7 @@ void test_suite(int argc, char **argv)
sums[3] += y * stbir__filter_bilinear(x+o); sums[3] += y * stbir__filter_bilinear(x+o);
} }
for (i=0; i < 3; ++i) for (i=0; i < 3; ++i)
STBIR_ASSERT(sums[i] >= 1.0 - 0.02 && sums[i] <= 1.0 + 0.02); STBIR_ASSERT(sums[i] >= 1.0 - 0.0170 && sums[i] <= 1.0 + 0.0170);
} }
} }
#endif #endif