/* * * Copyright 2002 Robert Krawitz (rlk@alum.mit.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef __GNU_LIBRARY__ #include #endif #pragma GCC diagnostic ignored "-Woverlength-strings" #define DEBUG_SIGNAL #define MIN(x, y) ((x) <= (y) ? (x) : (y)) #include int global_test_count = 0; int global_error_count = 0; int verbose = 0; int quiet = 0; #ifdef __GNU_LIBRARY__ struct option optlist[] = { { "quiet", 0, NULL, (int) 'q' }, { "verbose", 0, NULL, (int) 'v' }, { NULL, 0, NULL, 0 } }; #endif struct test_failure { int test_number; struct test_failure *next; }; static struct test_failure *test_failure_head = NULL; static struct test_failure *test_failure_tail = NULL; static const char *current_test_name; static int current_test_line; static void TEST_internal(const char *name, int line) { global_test_count++; current_test_name = name; current_test_line = line; } #define TEST(name) TEST_internal(name, __LINE__) static void TEST_PASS(void) { if (verbose) printf("%d.%d: Checking %s... PASS\n", global_test_count, current_test_line, current_test_name); fflush(stdout); } static void TEST_FAIL(void) { struct test_failure *test_failure_tmp = malloc(sizeof(struct test_failure)); test_failure_tmp->next = NULL; test_failure_tmp->test_number = global_test_count; if (!test_failure_head) { test_failure_head = test_failure_tmp; test_failure_tail = test_failure_head; } else { test_failure_tail->next = test_failure_tmp; test_failure_tail = test_failure_tmp; } global_error_count++; printf("%d.%d: Checking %s... FAIL\n", global_test_count, current_test_line, current_test_name); fflush(stdout); } #define SIMPLE_TEST_CHECK(conditional) \ do { \ if ((conditional)) \ TEST_PASS(); \ else \ TEST_FAIL(); \ } while (0) static const double standard_sat_adjustment[] = { 0.50, 0.6, 0.7, 0.8, 0.9, 0.86, 0.82, 0.79, /* C */ 0.78, 0.8, 0.83, 0.87, 0.9, 0.95, 1.05, 1.15, /* B */ 1.3, 1.25, 1.2, 1.15, 1.12, 1.09, 1.06, 1.03, /* M */ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, /* R */ 1.0, 0.9, 0.8, 0.7, 0.65, 0.6, 0.55, 0.52, /* Y */ 0.48, 0.47, 0.47, 0.49, 0.49, 0.49, 0.52, 0.51, /* G */ }; static const double reverse_sat_adjustment[] = { 0.50, 0.51, 0.52, 0.49, 0.49, 0.49, 0.47, 0.47, 0.48, 0.52, 0.55, 0.6, 0.65, 0.7, 0.8, 0.9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.03, 1.06, 1.09, 1.12, 1.15, 1.2, 1.25, 1.3, 1.15, 1.05, 0.95, 0.9, 0.87, 0.83, 0.8, 0.78, 0.79, 0.82, 0.86, 0.9 , 0.8, 0.7, 0.6, }; static const stp_curve_point_t standard_piecewise_sat_adjustment[] = { { 0.00, 0.50}, { 0.02, 0.6}, { 0.04, 0.7}, { 0.06, 0.8}, { 0.08, 0.9}, { 0.10, 0.86}, { 0.12, 0.82}, { 0.14, 0.79}, { 0.16, 0.78}, { 0.18, 0.8}, { 0.20, 0.83}, { 0.22, 0.87}, { 0.24, 0.9}, { 0.26, 0.95}, { 0.28, 1.05}, { 0.30, 1.15}, { 0.32, 0.05}, { 0.34, 3.95}, { 0.36, 0.05}, { 0.38, 1.15}, { 0.40, 1.12}, { 0.42, 1.09}, { 0.44, 1.06}, { 0.46, 1.03}, { 0.48, 1.0}, { 0.50, 1.0}, { 0.52, 1.0}, { 0.54, 1.0}, { 0.56, 1.0}, { 0.58, 1.0}, { 0.60, 1.0}, { 0.62, 1.0}, { 0.64, 1.0}, { 0.66, 0.9}, { 0.68, 0.8}, { 0.70, 0.7}, { 0.72, 0.65}, { 0.74, 0.6}, { 0.76, 0.55}, { 0.78, 0.52}, { 0.80, 0.48}, { 0.82, 0.47}, { 0.84, 0.47}, { 0.86, 0.49}, { 0.88, 0.49}, { 0.90, 0.49}, { 0.93, 0.52}, { 0.96, 0.51}, { 1.00, 2}, }; static const stp_curve_point_t reverse_piecewise_sat_adjustment[] = { { 0.00, 0.50}, { 0.02, 0.6}, { 0.04, 0.7}, { 0.06, 0.8}, { 0.08, 0.9}, { 0.10, 0.86}, { 0.12, 0.82}, { 0.14, 0.79}, { 0.16, 0.78}, { 0.18, 0.8}, { 0.20, 0.83}, { 0.22, 0.87}, { 0.24, 0.9}, { 0.26, 0.95}, { 0.28, 1.05}, { 0.30, 1.15}, { 0.32, 0.05}, { 0.34, 3.95}, { 0.36, 0.05}, { 0.38, 1.15}, { 0.40, 1.12}, { 0.42, 1.09}, { 0.44, 1.06}, { 0.46, 1.03}, { 0.48, 1.0}, { 0.50, 1.0}, { 0.52, 1.0}, { 0.54, 1.0}, { 0.56, 1.0}, { 0.58, 1.0}, { 0.60, 1.0}, { 0.62, 1.0}, { 0.64, 1.0}, { 0.66, 0.9}, { 0.68, 0.8}, { 0.70, 0.7}, { 0.72, 0.65}, { 0.74, 0.6}, { 0.76, 0.55}, { 0.78, 0.52}, { 0.80, 0.48}, { 0.82, 0.47}, { 0.84, 0.47}, { 0.86, 0.49}, { 0.88, 0.49}, { 0.90, 0.49}, { 0.93, 0.52}, { 0.96, 0.51}, { 1.00, 2}, }; const char *small_piecewise_curve = "\n" "\n" "\n" "\n" "0 0.5 0.1 0.6 1.00 0.51\n" "\n" "\n" "\n"; const char *good_curves[] = { /* Space separated, in same layout as output for comparison */ "\n" "\n" "\n" "\n" "0.5 0.6 0.7 0.8 0.9 0.86 0.82 0.79 0.78 0.8 0.83 0.87 0.9 0.95 1.05 1.15\n" "1.3 1.25 1.2 1.15 1.12 1.09 1.06 1.03 1 1 1 1 1 1 1 1 1 0.9 0.8 0.7 0.65\n" "0.6 0.55 0.52 0.48 0.47 0.47 0.49 0.49 0.49 0.52 0.51\n" "\n" "\n" "\n", /* Space separated, in same layout as output for comparison */ "\n" "\n" "\n" "\n" "0.5 0.6 0.7 0.8 0.9 0.86 0.82 0.79 0.78 0.8 0.83 0.87 0.9 0.95 1.05 1.15\n" "1.3 1.25 1.2 1.15 1.12 1.09 1.06 1.03 1 1 1 1 1 1 1 1 1 0.9 0.8 0.7 0.65\n" "0.6 0.55 0.52 0.48 0.47 0.47 0.49 0.49 0.49 0.52 0.51\n" "\n" "\n" "\n", /* Space separated, in same layout as output for comparison */ "\n" "\n" "\n" "\n" "0.5 0.6 0.7 0.8 0.9 0.86 0.82 0.79 0.78 0.8 0.83 0.87 0.9 0.95 1.05 1.15\n" "1.3 1.25 1.2 1.15 1.12 1.09 1.06 1.03 1 1 1 1 1 1 1 1 1 0.9 0.8 0.7 0.65\n" "0.6 0.55 0.52 0.48 0.47 0.47 0.49 0.49 0.49 0.52 0.51\n" "\n" "\n" "\n", /* Space separated, in same layout as output for comparison */ "\n" "\n" "\n" "\n" "0.5 0.6 0.7 0.8 0.9 0.86 0.82 0.79 0.78 0.8 0.83 0.87 0.9 0.95 1.05 1.15\n" "1.3 1.25 1.2 1.15 1.12 1.09 1.06 1.03 1 1 1 1 1 1 1 1 1 0.9 0.8 0.7 0.65\n" "0.6 0.55 0.52 0.48 0.47 0.47 0.49 0.49 0.49 0.52 0.51\n" "\n" "\n" "\n", "\n" "\n" "\n" "\n" "0 0.5 0.02 0.6 0.04 0.7 0.06 0.8 0.08 0.9 0.1 0.86 0.12 0.82 0.14 0.79 0.16\n" "0.78 0.18 0.8 0.2 0.83 0.22 0.87 0.24 0.9 0.26 0.95 0.28 1.05 0.3 1.15 0.32\n" "1.3 0.34 1.25 0.36 1.2 0.38 1.15 0.4 1.12 0.42 1.09 0.44 1.06 0.46 1.03\n" "0.48 1 0.5 1 0.52 1 0.54 1 0.56 1 0.58 1 0.6 1 0.62 1 0.64 1 0.66 0.9 0.68\n" "0.8 0.7 0.7 0.72 0.65 0.74 0.6 0.76 0.55 0.78 0.52 0.8 0.48 0.82 0.47 0.84\n" "0.47 0.86 0.49 0.88 0.49 0.9 0.49 0.93 0.52 0.96 0.51\n" "\n" "\n" "\n", "\n" "\n" "\n" "\n" "0 0.5 0.02 0.6 0.96 0.51\n" "\n" "\n" "\n", /* Gamma curve 1 */ "\n" "\n" "\n" "\n" "\n" "\n", /* Gamma curve 2 */ "\n" "\n" "\n" "\n" "\n" "\n" }; static const int good_curve_count = sizeof(good_curves) / sizeof(const char *); const char *bad_curves[] = { /* Bad point count */ "\n" "\n" "\n" "0.5 0.6 0.7 0.8 0.9 0.86 0.82 0.79 0.78 0.8\n" "0.83 0.87 0.9 0.95 1.05 1.15 1.3 1.25 1.2 1.15\n" "1.12 1.09 1.06 1.03 1 1 1 1 1 1\n" "1 1 1 0.9 0.8 0.7 0.65 0.6 0.55 0.52\n" "0.48 0.47 0.47 0.49 0.49 0.49 0.52 0.51\n" "\n", /* Bad point count */ "\n" "\n" "\n" "0.5 0.6 0.7 0.8 0.9 0.86 0.82 0.79 0.78 0.8\n" "0.83 0.87 0.9 0.95 1.05 1.15 1.3 1.25 1.2 1.15\n" "1.12 1.09 1.06 1.03 1 1 1 1 1 1\n" "1 1 1 0.9 0.8 0.7 0.65 0.6 0.55 0.52\n" "0.48 0.47 0.47 0.49 0.49 0.49 0.52 0.51\n" "\n", "\n" "\n" "\n" "\n" "0 0.5 0.02 0.6 0.96\n" "\n" "\n" "\n", "\n" "\n" "\n" "\n" "0 0.5 0.02 0.6 0.96 0.51\n" "\n" "\n" "\n", "\n" "\n" "\n" "\n" "0.01 0.5 0.02 0.6 1.0 0.51\n" "\n" "\n" "\n", /* Gamma curves */ /* Incorrect wrap mode */ "\n" "\n" "\n" "\n", "\n" "\n" "\n" "\n", "\n" "\n" "\n" "\n", "\n" "\n" "\n" "\n" }; static const int bad_curve_count = sizeof(bad_curves) / sizeof(const char *); const char *linear_curve_1 = "\n" "\n" "\n" "0 0 0 1 1 1" ""; const char *linear_curve_2 = "\n" "\n" "\n" "0 0 0 1 1 1" ""; const char *linear_curve_3 = "\n" "\n" "\n" "0 0 0 1 1 1" ""; const char *linear_curve_4 = "\n" "\n" "\n" "0 0 0 1 1 1" ""; const char *spline_curve_1 = "\n" "\n" "\n" "0 0 0 1 1 1" ""; const char *spline_curve_2 = "\n" "\n" "\n" "0 0 0 1 1 1" ""; static void piecewise_curve_checks(stp_curve_t *curve1, int resample_points, int expected) { stp_curve_t *curve2; const stp_curve_point_t *curve_points; size_t count; int i; double low; TEST("get data points of piecewise curve"); curve_points = stp_curve_get_data_points(curve1, &count); if (curve_points) { int bad_compare = 0; TEST_PASS(); TEST("Checking count of curve points"); if (count == expected) TEST_PASS(); else { TEST_FAIL(); if (!quiet) printf("Expected %d points, got %lu\n", expected, count); } TEST("Comparing data"); for (i = 0; i < count; i++) { if (curve_points[i].x != standard_piecewise_sat_adjustment[i].x || curve_points[i].y - .0000001 > standard_piecewise_sat_adjustment[i].y || curve_points[i].y + .0000001 < standard_piecewise_sat_adjustment[i].y) { bad_compare = 1; if (!quiet) printf("Miscompare at element %d: (%f, %f) (%f, %f)\n", i, standard_piecewise_sat_adjustment[i].x, standard_piecewise_sat_adjustment[i].y, curve_points[i].x, curve_points[i].y); } } SIMPLE_TEST_CHECK(!bad_compare); } else TEST_FAIL(); TEST("get sequence of piecewise curve (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!stp_curve_get_sequence(curve1)); TEST("get data of piecewise curve (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!stp_curve_get_data(curve1, &count)); TEST("set data point of piecewise curve (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!stp_curve_set_point(curve1, 2, 1.0)); TEST("get data point of piecewise curve (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!stp_curve_get_point(curve1, 2, &low)); TEST("interpolate piecewise curve (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!stp_curve_interpolate_value(curve1, .5, &low)); TEST("rescale piecewise curve"); SIMPLE_TEST_CHECK(stp_curve_rescale(curve1, .5, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE)); TEST("get float data of piecewise curve (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!stp_curve_get_float_data(curve1, &count)); TEST("get subrange on piecewise curve (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!(curve2 = stp_curve_get_subrange(curve1, 0, 2))); if (!quiet && curve2) stp_curve_write(stdout, curve2); TEST("set subrange on piecewise curve (PASS is an expected failure)"); curve2 = stp_curve_create_from_string(linear_curve_2); if (stp_curve_set_subrange(curve1, curve2, 1)) { TEST_FAIL(); if (!quiet) stp_curve_write(stdout, curve2); } else TEST_PASS(); stp_curve_destroy(curve2); if (resample_points > 0) { char tmpbuf[64]; sprintf(tmpbuf, "resample piecewise curve to %d points", resample_points); TEST(tmpbuf); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, resample_points)); TEST("resampled curve is not piecewise"); SIMPLE_TEST_CHECK(!stp_curve_is_piecewise(curve1)); TEST("get data points of piecewise copy (PASS is an expected failure)"); SIMPLE_TEST_CHECK(!stp_curve_get_data_points(curve1, &count)); TEST("get sequence of piecewise copy"); SIMPLE_TEST_CHECK(stp_curve_get_sequence(curve1)); TEST("get data of piecewise copy"); SIMPLE_TEST_CHECK(stp_curve_get_data(curve1, &count)); TEST("set data point of piecewise copy"); SIMPLE_TEST_CHECK(stp_curve_set_point(curve1, 2, 0.51)); TEST("get data point of piecewise copy"); SIMPLE_TEST_CHECK(stp_curve_get_point(curve1, 2, &low)); TEST("interpolate piecewise copy"); SIMPLE_TEST_CHECK(stp_curve_interpolate_value(curve1, .5, &low)); TEST("rescale piecewise copy"); SIMPLE_TEST_CHECK(stp_curve_rescale(curve1, 2, STP_CURVE_COMPOSE_MULTIPLY, STP_CURVE_BOUNDS_RESCALE)); TEST("get float data of piecewise copy"); SIMPLE_TEST_CHECK(stp_curve_get_float_data(curve1, &count)); TEST("get subrange on piecewise copy"); SIMPLE_TEST_CHECK((curve2 = stp_curve_get_subrange(curve1, 0, 2))); if (verbose && curve2) stp_curve_write(stdout, curve2); if (curve2) stp_curve_destroy(curve2); if (resample_points > 10) { TEST("set subrange on piecewise copy"); curve2 = stp_curve_create_from_string(linear_curve_2); if (verbose) stp_curve_write(stdout, curve1); if (stp_curve_set_subrange(curve1, curve2, 4)) { TEST_PASS(); if (verbose) stp_curve_write(stdout, curve1); } else TEST_FAIL(); if (curve2) stp_curve_destroy(curve2); } } } int main(int argc, char **argv) { char *tmp; int i; size_t count; double low, high; stp_curve_t *curve1; stp_curve_t *curve2; stp_curve_t *curve3; const stp_curve_point_t *curve_points; while (1) { #ifdef __GNU_LIBRARY__ int option_index = 0; int c = getopt_long(argc, argv, "qv", optlist, &option_index); #else int c = getopt(argc, argv, "qv"); #endif if (c == -1) break; switch (c) { case 'q': quiet = 1; verbose = 0; break; case 'v': quiet = 0; verbose = 1; break; default: break; } } stp_init(); TEST("creation of XML string from curve"); curve1 = stp_curve_create(STP_CURVE_WRAP_AROUND); stp_curve_set_bounds(curve1, 0.0, 4.0); stp_curve_set_data(curve1, 48, reverse_sat_adjustment); tmp = stp_curve_write_string(curve1); stp_curve_destroy(curve1); curve1 = NULL; SIMPLE_TEST_CHECK(tmp); if (verbose) printf("%s\n", tmp); TEST("creation of curve from XML string (stp_curve_create_from_string)"); SIMPLE_TEST_CHECK((curve2 = stp_curve_create_from_string(tmp))); free(tmp); TEST("stp_curve_resample"); if (curve2 != NULL && stp_curve_resample(curve2, 95) == 0) { TEST_FAIL(); } else { TEST_PASS(); if (verbose) stp_curve_write(stdout, curve2); } if (curve2) { stp_curve_destroy(curve2); curve2 = NULL; } if (!quiet) printf("Testing known bad curves... (expect messages)\n"); for (i = 0; i < bad_curve_count; i++) { stp_curve_t *bad = NULL; TEST("BAD curve (PASS is an expected failure)"); if ((bad = stp_curve_create_from_string(bad_curves[i])) != NULL) { TEST_FAIL(); if (!quiet) { stp_curve_write(stdout, bad); printf("\n"); } stp_curve_destroy(bad); bad = NULL; } else TEST_PASS(); } if (!quiet) printf("Testing known good curves...\n"); for (i = 0; i < good_curve_count; i++) { if (curve2) { stp_curve_destroy(curve2); curve2 = NULL; } TEST("GOOD curve"); if ((curve2 = stp_curve_create_from_string(good_curves[i])) != NULL) { TEST_PASS(); tmp = stp_curve_write_string(curve2); TEST("whether XML curve is identical to original"); if (tmp && strcmp((const char *) tmp, good_curves[i])) { TEST_FAIL(); if (!quiet) { printf("XML:\n"); printf("%s", tmp); printf("Original:\n"); printf("%s", good_curves[i]); printf("End:\n"); } } else { TEST_PASS(); if (verbose) printf("%s", tmp); } free(tmp); } else TEST_FAIL(); } if (curve2) { stp_curve_destroy(curve2); curve2 = NULL; } if (verbose) printf("Allocate 1\n"); curve1 = stp_curve_create(STP_CURVE_WRAP_NONE); if (verbose) printf("Allocate 2\n"); curve2 = stp_curve_create(STP_CURVE_WRAP_NONE); TEST("set curve 1 gamma"); SIMPLE_TEST_CHECK(stp_curve_set_gamma(curve1, 1.2)); if (verbose) stp_curve_write(stdout, curve1); TEST("set curve 2 gamma"); SIMPLE_TEST_CHECK(stp_curve_set_gamma(curve2, -1.2)); if (verbose) stp_curve_write(stdout, curve2); TEST("compose add from gamma curves"); SIMPLE_TEST_CHECK(stp_curve_compose(&curve3, curve1, curve2, STP_CURVE_COMPOSE_ADD, 64)); if (verbose && curve3) stp_curve_write(stdout, curve3); TEST("resample curve 1"); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, 64)); if (verbose && curve1) stp_curve_write(stdout, curve1); if (curve3) { stp_curve_destroy(curve3); curve3 = NULL; } TEST("compose multiply from gamma curves"); if (!stp_curve_compose(&curve3, curve1, curve2, STP_CURVE_COMPOSE_MULTIPLY, 64)) TEST_FAIL(); else { TEST_PASS(); if (verbose) { stp_curve_write(stdout, curve1); stp_curve_write(stdout, curve2); stp_curve_write(stdout, curve3); } } TEST("compose add from non-gamma curves"); stp_curve_destroy(curve1); stp_curve_destroy(curve2); stp_curve_destroy(curve3); curve1 = stp_curve_create_from_string(good_curves[0]); curve2 = stp_curve_create_from_string(linear_curve_2); SIMPLE_TEST_CHECK(stp_curve_compose(&curve3, curve1, curve2, STP_CURVE_COMPOSE_ADD, 64)); if (verbose && curve3) stp_curve_write(stdout, curve3); TEST("resample curve 1"); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, 64)); if (verbose && curve1) stp_curve_write(stdout, curve1); if (curve3) { stp_curve_destroy(curve3); curve3 = NULL; } TEST("compose multiply from non-gamma curves"); if (!stp_curve_compose(&curve3, curve1, curve2, STP_CURVE_COMPOSE_MULTIPLY, 64)) TEST_FAIL(); else { TEST_PASS(); if (verbose) { stp_curve_write(stdout, curve1); stp_curve_write(stdout, curve2); stp_curve_write(stdout, curve3); } } if (curve3) { stp_curve_destroy(curve3); curve3 = NULL; } TEST("multiply rescale"); SIMPLE_TEST_CHECK(stp_curve_rescale(curve2, -1, STP_CURVE_COMPOSE_MULTIPLY, STP_CURVE_BOUNDS_RESCALE)); if (verbose && curve2) stp_curve_write(stdout, curve2); TEST("subtract compose"); SIMPLE_TEST_CHECK(stp_curve_compose(&curve3, curve1, curve2, STP_CURVE_COMPOSE_ADD, 64)); if (verbose && curve3) stp_curve_write(stdout, curve3); if (curve3) { stp_curve_destroy(curve3); curve3 = NULL; } if (curve1) { stp_curve_destroy(curve1); curve1 = NULL; } if (curve2) { stp_curve_destroy(curve2); curve2 = NULL; } TEST("spline curve 1 creation"); SIMPLE_TEST_CHECK((curve1 = stp_curve_create_from_string(spline_curve_1))); TEST("spline curve 2 creation"); SIMPLE_TEST_CHECK((curve2 = stp_curve_create_from_string(spline_curve_2))); if (curve1) { if (verbose) stp_curve_write(stdout, curve1); TEST("spline curve 1 resample 1"); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, 41)); if (verbose && curve1) stp_curve_write(stdout, curve1); TEST("spline curve 1 resample 2"); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, 83)); if (verbose && curve1) stp_curve_write(stdout, curve1); } if (curve2) { if (verbose) stp_curve_write(stdout, curve2); TEST("spline curve 2 resample"); SIMPLE_TEST_CHECK(stp_curve_resample(curve2, 48)); if (verbose && curve2) stp_curve_write(stdout, curve2); } TEST("compose add (PASS is an expected failure)"); if (curve1 && curve2 && stp_curve_compose(&curve3, curve1, curve2, STP_CURVE_COMPOSE_MULTIPLY, -1)) { TEST_FAIL(); if (!quiet) printf("compose with different wrap mode should fail!\n"); } else TEST_PASS(); if (curve1) { stp_curve_destroy(curve1); curve1 = NULL; } if (curve2) { stp_curve_destroy(curve2); curve2 = NULL; } TEST("linear curve 1 creation"); SIMPLE_TEST_CHECK((curve1 = stp_curve_create_from_string(linear_curve_1))); TEST("linear curve 2 creation"); SIMPLE_TEST_CHECK((curve2 = stp_curve_create_from_string(linear_curve_2))); TEST("get data points of dense curve (PASS is an expected failure)"); curve_points = stp_curve_get_data_points(curve2, &count); SIMPLE_TEST_CHECK(!curve_points); if (curve1) { if (verbose) stp_curve_write(stdout, curve1); TEST("linear curve 1 resample"); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, 41)); if (verbose && curve1) stp_curve_write(stdout, curve1); stp_curve_destroy(curve1); curve1 = NULL; } if (curve2) { if (verbose) stp_curve_write(stdout, curve2); TEST("linear curve 2 resample"); SIMPLE_TEST_CHECK(stp_curve_resample(curve2, 48)); if (verbose && curve2) stp_curve_write(stdout, curve2); stp_curve_destroy(curve2); curve2 = NULL; } curve1 = stp_curve_create(STP_CURVE_WRAP_AROUND); stp_curve_set_interpolation_type(curve1, STP_CURVE_TYPE_SPLINE); stp_curve_set_bounds(curve1, 0.0, 4.0); stp_curve_set_data(curve1, 48, standard_sat_adjustment); TEST("setting curve data"); SIMPLE_TEST_CHECK(curve1 && (stp_curve_count_points(curve1) == 48)); if (verbose) stp_curve_write(stdout, curve1); TEST("curve resample"); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, 384)); if (verbose) stp_curve_write(stdout, curve1); TEST("very large curve resample"); SIMPLE_TEST_CHECK(stp_curve_resample(curve1, 65535)); TEST("offsetting large curve"); #if 0 stp_curve_get_range(curve1, &low, &high); fprintf(stderr, "Result original max %f min %f\n", high, low); stp_curve_get_bounds(curve1, &low, &high); fprintf(stderr, "Bounds original max %f min %f\n", high, low); #endif SIMPLE_TEST_CHECK(stp_curve_rescale(curve1, 2.0, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE)); stp_curve_rescale(curve1, 1.0, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); stp_curve_get_bounds(curve1, &low, &high); stp_curve_rescale(curve1, 0.0, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); stp_curve_get_bounds(curve1, &low, &high); stp_curve_rescale(curve1, 0.0, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); stp_curve_get_bounds(curve1, &low, &high); stp_curve_rescale(curve1, 0.0, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); stp_curve_get_bounds(curve1, &low, &high); TEST("writing very large curve to string"); tmp = stp_curve_write_string(curve1); if (tmp == NULL) TEST_FAIL(); else TEST_PASS(); if (tmp) { TEST("reading back very large curve"); curve2 = stp_curve_create_from_string(tmp); SIMPLE_TEST_CHECK(stp_curve_count_points(curve2) == 65535); free(tmp); TEST("Rescaling readback"); SIMPLE_TEST_CHECK(stp_curve_rescale(curve2, -1.0, STP_CURVE_COMPOSE_MULTIPLY, STP_CURVE_BOUNDS_RESCALE)); TEST("Adding curves"); SIMPLE_TEST_CHECK(stp_curve_compose(&curve3, curve1, curve2, STP_CURVE_COMPOSE_ADD, 65535)); stp_curve_get_range(curve3, &low, &high); TEST("Comparing results"); SIMPLE_TEST_CHECK(low < .00001 && low > -.00001 && high < .00001 && high > -.00001); if (curve1) { stp_curve_destroy(curve1); curve1 = NULL; } if (curve2) { stp_curve_destroy(curve2); curve2 = NULL; } } TEST("Creating piecewise wrap-around curve"); curve1 = stp_curve_create(STP_CURVE_WRAP_AROUND); stp_curve_set_bounds(curve1, 0.0, 4.0); SIMPLE_TEST_CHECK(stp_curve_set_data_points (curve1, 48, reverse_piecewise_sat_adjustment)); TEST("Writing piecewise wrap-around curve to string"); tmp = stp_curve_write_string(curve1); SIMPLE_TEST_CHECK(tmp); if (verbose) printf("%s\n", tmp); stp_free(tmp); TEST("Check curve is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve1)); TEST("Create copy of piecewise curve"); curve2 = stp_curve_create_copy(curve1); SIMPLE_TEST_CHECK(curve2); TEST("Check copy is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve2)); piecewise_curve_checks(curve1, 0, 48); stp_curve_rescale(curve1, -.5, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); piecewise_curve_checks(curve2, 3, 48); TEST("Copy in place piecewise curve"); stp_curve_copy(curve2, curve1); SIMPLE_TEST_CHECK(curve1 != NULL); piecewise_curve_checks(curve2, 10, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 15, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 47, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 48, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 49, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 50, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 100, 48); stp_curve_destroy(curve1); stp_curve_destroy(curve2); TEST("Creating piecewise no-wrap curve with not enough data (PASS is an expected failure)"); curve1 = stp_curve_create(STP_CURVE_WRAP_NONE); stp_curve_set_bounds(curve1, 0.0, 4.0); SIMPLE_TEST_CHECK(!stp_curve_set_data_points (curve1, 48, standard_piecewise_sat_adjustment)); TEST("Creating piecewise no-wrap curve correctly"); SIMPLE_TEST_CHECK(stp_curve_set_data_points (curve1, 49, standard_piecewise_sat_adjustment)); TEST("Writing piecewise no-wrap curve to string"); tmp = stp_curve_write_string(curve1); SIMPLE_TEST_CHECK(tmp); if (verbose) printf("%s\n", tmp); stp_free(tmp); TEST("Check curve is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve1)); TEST("Create copy of piecewise curve"); curve2 = stp_curve_create_copy(curve1); SIMPLE_TEST_CHECK(curve2); TEST("Check copy is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve2)); piecewise_curve_checks(curve1, 0, 49); stp_curve_rescale(curve1, -.5, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); piecewise_curve_checks(curve2, 3, 49); TEST("Copy in place piecewise curve"); stp_curve_copy(curve2, curve1); SIMPLE_TEST_CHECK(curve1 != NULL); piecewise_curve_checks(curve2, 10, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 15, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 47, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 48, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 49, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 50, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 100, 49); stp_curve_destroy(curve2); stp_curve_destroy(curve1); TEST("Creating piecewise spline wrap-around curve"); curve1 = stp_curve_create(STP_CURVE_WRAP_AROUND); stp_curve_set_interpolation_type(curve1, STP_CURVE_TYPE_SPLINE); stp_curve_set_bounds(curve1, 0.0, 4.0); SIMPLE_TEST_CHECK(stp_curve_set_data_points (curve1, 48, standard_piecewise_sat_adjustment)); TEST("Writing piecewise wrap-around curve to string"); tmp = stp_curve_write_string(curve1); SIMPLE_TEST_CHECK(tmp); if (verbose) printf("%s\n", tmp); stp_free(tmp); TEST("Check curve is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve1)); TEST("Create copy of piecewise curve"); curve2 = stp_curve_create_copy(curve1); SIMPLE_TEST_CHECK(curve2); TEST("Check copy is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve2)); piecewise_curve_checks(curve1, 0, 48); stp_curve_rescale(curve1, -.5, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); piecewise_curve_checks(curve2, 3, 48); TEST("Copy in place piecewise curve"); stp_curve_copy(curve2, curve1); SIMPLE_TEST_CHECK(curve1 != NULL); piecewise_curve_checks(curve2, 10, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 15, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 47, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 48, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 49, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 50, 48); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 100, 48); stp_curve_destroy(curve1); TEST("Creating piecewise spline wrap-around curve"); curve1 = stp_curve_create(STP_CURVE_WRAP_NONE); stp_curve_set_interpolation_type(curve1, STP_CURVE_TYPE_SPLINE); stp_curve_set_bounds(curve1, 0.0, 4.0); SIMPLE_TEST_CHECK(stp_curve_set_data_points (curve1, 49, standard_piecewise_sat_adjustment)); TEST("Writing piecewise no-wrap curve to string"); tmp = stp_curve_write_string(curve1); SIMPLE_TEST_CHECK(tmp); if (verbose) printf("%s\n", tmp); stp_free(tmp); TEST("Check curve is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve1)); if (curve2) { stp_curve_destroy(curve2); curve2 = NULL; } TEST("Create copy of piecewise curve"); curve2 = stp_curve_create_copy(curve1); SIMPLE_TEST_CHECK(curve2); TEST("Check copy is piecewise"); SIMPLE_TEST_CHECK(stp_curve_is_piecewise(curve2)); piecewise_curve_checks(curve1, 0, 49); stp_curve_rescale(curve1, -.5, STP_CURVE_COMPOSE_ADD, STP_CURVE_BOUNDS_RESCALE); piecewise_curve_checks(curve2, 3, 49); TEST("Copy in place piecewise curve"); stp_curve_copy(curve2, curve1); SIMPLE_TEST_CHECK(curve1 != NULL); piecewise_curve_checks(curve2, 10, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 15, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 47, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 48, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 49, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 50, 49); stp_curve_copy(curve2, curve1); piecewise_curve_checks(curve2, 100, 49); stp_curve_destroy(curve1); TEST("Create small piecewise curve"); curve1 = stp_curve_create_from_string(small_piecewise_curve); SIMPLE_TEST_CHECK(curve1); stp_curve_destroy(curve1); curve1 = NULL; stp_curve_destroy(curve2); curve2 = NULL; stp_curve_destroy(curve3); curve3 = NULL; if (global_error_count) { printf("%d/%d tests FAILED.\n", global_error_count, global_test_count); printf("Failures:\n"); while (test_failure_head) { printf(" %3d\n", test_failure_head->test_number); test_failure_head = test_failure_head->next; } } else printf("All %d tests passed successfully.\n", global_test_count); return global_error_count ? 1 : 0; }