bool test_contrib_windows(flow_c * context, char * msg)
{
    int bad = -1;
    struct flow_interpolation_line_contributions * lct = 0;

    // assumes included edge cases

    struct flow_interpolation_details *triangle = flow_interpolation_details_create_from(
        context, flow_interpolation_filter::flow_interpolation_filter_Triangle);

    unsigned int from_w = 6;
    unsigned int to_w = 3;
    unsigned int corr36[3][2] = { { 0, 2 }, { 1, 4 }, { 3, 5 } };
    lct = flow_interpolation_line_contributions_create(context, to_w, from_w, triangle);

    for (uint32_t i = 0; i < lct->LineLength; i++)
        if (lct->ContribRow[i].Left != (int)corr36[i][0]) {
            bad = i;
            break;
        } else if (lct->ContribRow[i].Right != (int)corr36[i][1]) {
            bad = i;
            break;
        }

    if (bad != -1) {
        flow_snprintf(msg, 255, "at 6->3 invalid value (%d; %d) at %d, expected (%d; %d)", lct->ContribRow[bad].Left,
                      lct->ContribRow[bad].Right, bad, corr36[bad][0], corr36[bad][1]);
        flow_interpolation_line_contributions_destroy(context, lct);
        return false;
    }
    flow_interpolation_line_contributions_destroy(context, lct);

    from_w = 6;
    to_w = 4;
    unsigned int corr46[4][2] = { { 0, 1 }, { 1, 3 }, { 2, 4 }, { 4, 5 } };
    lct = flow_interpolation_line_contributions_create(context, to_w, from_w, triangle);
    flow_interpolation_details_destroy(context, triangle);

    for (uint32_t i = 0; i < lct->LineLength; i++)
        if (lct->ContribRow[i].Left != (int)corr46[i][0]) {
            bad = i;
            break;
        } else if (lct->ContribRow[i].Right != (int)corr46[i][1]) {
            bad = i;
            break;
        }

    if (bad != -1) {
        flow_snprintf(msg, 255, "at 6->4 invalid value (%d; %d) at %d, expected (%d; %d)", lct->ContribRow[bad].Left,
                      lct->ContribRow[bad].Right, bad, corr46[bad][0], corr46[bad][1]);
        flow_interpolation_line_contributions_destroy(context, lct);
        return false;
    }
    flow_interpolation_line_contributions_destroy(context, lct);
    return true;
}
Exemplo n.º 2
0
static bool checksum_bitmap(flow_c * c, struct flow_bitmap_bgra * bitmap, char * checksum_buffer,
                            size_t checksum_buffer_length)
{
    char info_buffer[256];
    flow_snprintf(&info_buffer[0], sizeof(info_buffer), "%dx%d fmt=%d alpha=%d", bitmap->w, bitmap->h, bitmap->fmt,
                  bitmap->alpha_meaningful);
    int64_t printed_chars = (flow_snprintf(checksum_buffer, checksum_buffer_length, "%016X_%016X",
                                           djb2_buffer((uint8_t *)bitmap->pixels, bitmap->stride * bitmap->h),
                                           djb2((unsigned const char *)&info_buffer[0])));

    return printed_chars != -1;
}
bool test_details(flow_c * context, struct flow_interpolation_details * details, char * msg,
                  double expected_first_crossing, double expected_second_crossing, double expected_near0,
                  double near0_threshold, double expected_end)
{
    double top = (*details->filter)(details, 0);

    // Verify peak is at x = 0
    if (!function_bounded_bi(context, details, msg, 0, expected_end, 0.05, -500, top, "should peak at x=0"))
        return false;

    // Verify we drop below a certain threshold between expected_near0 and expected_second_crossing or expected_end
    if (!function_bounded_bi(context, details, msg, expected_near0,
                             expected_second_crossing > 0 ? expected_second_crossing : expected_end, 0.05, -500,
                             near0_threshold, "should near 0"))
        return false;

    char sub_msg[1024];
    flow_snprintf(sub_msg, 1024, "should end at expected_end (%f)", expected_end);

    // Ensure ended at expected_end
    if (!function_bounded_bi(context, details, msg, expected_end, expected_end + 1, 0.05, -0.0001f, 0.0001f,
                             sub_msg))
        return false;

    if (expected_first_crossing != 0 && expected_second_crossing != 0) {
        // Ensure everything between the two crossings is negative
        if (!function_bounded_bi(context, details, msg, expected_first_crossing + 0.05, expected_second_crossing - 0.05,
                                 0.05, -500, -0.0001f, "should be negative between crossing 1 and 2"))
            return false;

        // Ensure everything between second crossing and end is positive - if significant
        if (expected_end > expected_second_crossing + 0.1) {

            flow_snprintf(sub_msg, 1024, "should be positive between crossing 2 (%f) and end (%f)", expected_second_crossing, expected_end);
            if (!function_bounded_bi(context, details, msg, expected_second_crossing + 0.05, expected_end - 0.02, 0.02,
                                     0, 500, sub_msg))
                return false;
        }
    } else {
        // Ensure everything is non-negative
        if (!function_bounded_bi(context, details, msg, expected_near0, expected_end, 0.05, -0.0001, 500,
                                 "this function should only produce positive weights"))
            return false;
    }

    return true;
}
Exemplo n.º 4
0
static bool diff_images(flow_c * c, char * checksum_a, char * checksum_b, double * out_dssim, bool generate_visual_diff,
                       const char * storage_relative_to)
{
    char filename_a[2048];
    if (!create_path_from_relative(c, storage_relative_to, false, filename_a, 2048, "/visuals/%s.png", checksum_a)) {
        FLOW_add_to_callstack(c);
        return false;
    }
    char filename_b[2048];
    if (!create_path_from_relative(c, storage_relative_to, false, filename_b, 2048, "/visuals/%s.png", checksum_b)) {
        FLOW_add_to_callstack(c);
        return false;
    }
    char filename_c[2048];
    if (!create_path_from_relative(c, storage_relative_to, false, filename_c, 2048, "/visuals/compare_%s_vs_%s.png", checksum_a, checksum_b)) {
        FLOW_add_to_callstack(c);
        return false;
    }

    char magick_command[4096];
    flow_snprintf(magick_command, 4096, "dssim %s %s", filename_b, filename_a);
    *out_dssim = get_dssim_from_command(c, magick_command);
    if (*out_dssim > 10 || *out_dssim < 0) {
        fprintf(stderr, "Failed to execute: %s", magick_command);
        *out_dssim = 2.23456;
        // FLOW_error(c, flow_status_IO_error);
    };
    if (generate_visual_diff) {
        fprintf(stderr, "%s\n", &filename_c[0]);

        if (access(filename_c, F_OK) != -1) {
            return true; // Already exists!
        }
        flow_snprintf(magick_command, 4096, "composite %s %s -compose difference %s", filename_a, filename_b,
                      filename_c);

        int result = system(magick_command);
        if (result != 0) {
            fprintf(stderr, "unhappy imagemagick\n");
        }
    }
    return true;
}
char * test_filter(flow_c * context, flow_interpolation_filter filter, char * msg, double expected_first_crossing,
                   double expected_second_crossing, double expected_near0, double near0_threshold, double expected_end)
{
    struct flow_interpolation_details * details = flow_interpolation_details_create_from(context, filter);
    flow_snprintf(msg, 255, "Filter=(%d) ", filter);
    bool result = test_details(context, details, msg, expected_first_crossing, expected_second_crossing, expected_near0,
                               near0_threshold, expected_end);
    flow_interpolation_details_destroy(context, details);
    if (!result)
        return msg;
    else
        return nullptr;
}
bool function_bounded(flow_c * context, struct flow_interpolation_details * details, char * msg,
                      double input_start_value, double stop_at_abs, double input_step, double result_low_threshold,
                      double result_high_threshold, const char * name)
{
    double input_value = input_start_value;

    if (fabs(input_value) >= fabs(stop_at_abs))
        return true;

    double result_value = (*details->filter)(details, input_value);

    if (result_value < result_low_threshold) {
        flow_snprintf(msg + strlen(msg), 255 - strlen(msg), "value %.4f is below %.4f at x=%.4f (%s)", result_value,
                      result_low_threshold, input_value, name);
        return false;
    } else if (result_value > result_high_threshold) {
        flow_snprintf(msg + strlen(msg), 255 - strlen(msg), "value %.4f exceeds %.4f at x=%.4f (%s)", result_value,
                      result_high_threshold, input_value, name);
        return false;
    }

    return function_bounded(context, details, msg, input_value + input_step, stop_at_abs, input_step,
                            result_low_threshold, result_high_threshold, name);
}
Exemplo n.º 7
0
static bool download_by_checksum(flow_c * c, char * checksum, const char * storage_relative_to)
{
    char filename[2048];
    if (!create_path_from_relative(c, storage_relative_to, true, filename, 2048, "/visuals/%s.png", checksum)) {
        FLOW_add_to_callstack(c);
        return false;
    }

    fprintf(stderr, "%s (trusted)\n", &filename[0]);
    if (access(filename, F_OK) != -1) {
        return true; // Already exists!
    }
    char url[2048];
    flow_snprintf(url, 2048, "http://s3-us-west-2.amazonaws.com/imageflow-resources/visual_test_checksums/%s.png",
                  checksum); // TODO: fix actual URL
    if (!fetch_image(url, filename)) {
        FLOW_add_to_callstack(c);
        return false;
    }
    return true;
}