improve bwhist reporting of the median calculation (was wrong)

This commit is contained in:
Christopher Sean Morrison committed 2026-08-18 00:30:01 -04:00
1 parent 743178e15b
commit 2307575ef1
3 files changed
+64 -6

No files matched your search

+17 -6
View File
@@ -76,7 +76,7 @@ main(int argc, char **argv)
double d;
unsigned char *bp;
long num_pixels = 0L ;
long sum = 0L , partial_sum = 0L ;
long sum = 0L, cumulative_pixels = 0L, median_rank;
int max = -1, min = 256 , mode = 0 , median = 0 ;
double mean, var = 0.0 , skew = 0.0 ;
FILE *fp;
@@ -86,7 +86,7 @@ main(int argc, char **argv)
setmode(fileno(stdin), O_BINARY);
setmode(fileno(stdout), O_BINARY);
if (BU_STR_EQUAL(argv[1], "-h") || BU_STR_EQUAL(argv[1], "-?"))
if (argc > 1 && (BU_STR_EQUAL(argv[1], "-h") || BU_STR_EQUAL(argv[1], "-?")))
bu_exit(1, "%s", Usage);
/* check for verbose flag */
@@ -120,6 +120,16 @@ main(int argc, char **argv)
for (i = 0; i < n; i++)
bin[ *bp++ ]++;
}
if (ferror(fp)) {
bu_exit(1, "bwstat: error reading input\n");
}
if (fp != stdin) {
fclose(fp);
}
if (num_pixels == 0) {
bu_exit(1, "bwstat: input contains no pixels\n");
}
median_rank = num_pixels / 2 + num_pixels % 2;
/*
* Find sum, min, max, mode. (sum and mode initialized to 0;
@@ -143,13 +153,14 @@ main(int argc, char **argv)
/*
* Now do a second pass to compute median,
* variance and skew. (median and partial_sum initialized to 0;
* variance and skew. (median and cumulative_pixels initialized to 0;
* var and skew initialized to 0.0)
*/
for (i = 0; i < 256; i++) {
if (partial_sum < sum/2.0) {
partial_sum += i * bin[i];
median = i;
if (cumulative_pixels < median_rank) {
cumulative_pixels += bin[i];
if (cumulative_pixels >= median_rank)
median = i;
}
d = (double)i - mean;
var += bin[i] * d * d;
+8
View File
@@ -19,9 +19,17 @@ brlcad_add_test(
-P "${CMAKE_CURRENT_SOURCE_DIR}/test_pixembed_edge_replication.cmake"
)
brlcad_add_test(
NAME util_bwstat_statistics
COMMAND
"${CMAKE_COMMAND}" "-DBWSTAT=$<TARGET_FILE:bwstat>" "-DTEST_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/test_bwstat_statistics.cmake"
)
cmakefiles(
CMakeLists.txt
test_bwcrop_single_axis.cmake
test_bwstat_statistics.cmake
test_pixdiff_bytes.cmake
test_pixembed_edge_replication.cmake
)
@@ -0,0 +1,39 @@
if(NOT DEFINED BWSTAT OR NOT DEFINED TEST_DIR)
message(FATAL_ERROR "BWSTAT and TEST_DIR are required")
endif()
set(input_file "${TEST_DIR}/bwstat-input.bw")
set(empty_file "${TEST_DIR}/bwstat-empty.bw")
file(REMOVE "${input_file}" "${empty_file}")
string(ASCII 1 1 255 input_data)
file(WRITE "${input_file}" "${input_data}")
file(WRITE "${empty_file}" "")
execute_process(
COMMAND "${BWSTAT}" "${input_file}"
RESULT_VARIABLE bwstat_result
OUTPUT_VARIABLE bwstat_output
ERROR_VARIABLE bwstat_error
)
if(NOT bwstat_result EQUAL 0)
message(FATAL_ERROR "bwstat failed (${bwstat_result}): ${bwstat_error}")
endif()
if(NOT bwstat_output MATCHES "Median +1")
message(FATAL_ERROR "bwstat reported the wrong median:\n${bwstat_output}")
endif()
execute_process(
COMMAND "${BWSTAT}" "${empty_file}"
RESULT_VARIABLE bwstat_result
OUTPUT_VARIABLE bwstat_output
ERROR_VARIABLE bwstat_error
)
if(bwstat_result EQUAL 0)
message(FATAL_ERROR "bwstat accepted empty input:\n${bwstat_output}")
endif()
if(NOT bwstat_error MATCHES "input contains no pixels")
message(FATAL_ERROR "bwstat did not explain the empty input error:\n${bwstat_error}")
endif()
file(REMOVE "${input_file}" "${empty_file}")