Bläddra i källkod

Normalize downsample coefficients.

Jorge Rodriguez 11 år sedan
förälder
incheckning
497eab8339
2 ändrade filer med 31 tillägg och 9 borttagningar
  1. 13 7
      stb_image_resize.h
  2. 18 2
      tests/resample_test.cpp

+ 13 - 7
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;
 	int i;
 	for (i = 0; i < stbir_info->output_w; 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 > 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
 // 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.
 // 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));
 			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);
 	}
 	}
 }
 }
 
 

+ 18 - 2
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_BICUBIC, 1, value);
 	verify_filter_normalized(STBIR_FILTER_CATMULLROM, 1, value);
 	verify_filter_normalized(STBIR_FILTER_CATMULLROM, 1, value);
 	verify_filter_normalized(STBIR_FILTER_MITCHELL, 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	
 		#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 sums[4] = {0};
 				float o;
 				float o;
 				for (o=-5; o <= 5; o += y) {
 				for (o=-5; o <= 5; o += y) {