/* This file was generated by scramble.py. */
#include "iris.h"
#include "scramble.h"
void black_out_circle(Image *image, int x, int y, int r1, int r2)
{
    int w = image->w;
    int h = image->h;
    int sum = 0, n = 0;
    for (int j = 0; j < h; j++)
    {
        for (int i = 0; i < w ; i++)
        {
            int dx = i - x;
            int dy = j - y;
            int d = sqrt(dx * dx + dy * dy);
            if (d <= r2 && d >= r1)
            {
                int c = image->data.b[i + j * w];
                sum += c;
                n++;
            }
        }
    }
    sum /= n;
    for (int j = 0; j < h; j++)
    {
        for (int i = 0; i < w ; i++)
        {
            int dx = i - x;
            int dy = j - y;
            int d = sqrt(dx * dx + dy * dy);
            if (d <= r2)
            {
                int alpha = r2 * (d - r1) / (r2 - r1);
                if (alpha < 0)
                {
                    alpha = 0;
                }
                int c = image->data.b[i + j * w];
                image->data.b[i + j * w] = c * alpha / r2 + sum * (r2 - alpha) / r2;
            }
        }
    }
}
void dim_above_horizon(Image *image, int y, V a)
{
    int w = image->w;
    for (int j = 0; j < y; j++)
    {
        V val = (j - y) * (j - y) * a;
        val = 255 - val;
        if (val < 0)
        {
            val = 0;
        }
        for (int i = 0; i < w ; i++)
        {
            int c = image->data.b[i + j * w];
            image->data.b[i + j * w] = c * val / 255;
        }
    }
}
Image * find_iris(Image const *orig_image, char const *what, int px, int py, int pr, int *out_ix, int *out_iy, int *out_ir)
{
    Image *image = image_copy(orig_image);
    int w = image->w;
    int h = image->h;
    int min_r = pr * 1.5;
    /* Blackout the pupil first */
    black_out_circle(image, px, py, pr, min_r);
    if (what && strstr(what, "blackout"))
    {
        char name[MAX_PATH];
        get_image_name(image, "blackout", name);
        save_tiff_luminance(name, image);
    }
    int IRIS_HOUGH_THRESHOLD = 200;
    adjust_luminance(image, min_r * min_r * pi, w * h * 0.01);
    /* That's a hack so bright iris patterns cause less edges */
    threshold_above(image, 128, 128);
    /* Image *accum = cumulate(image, 3, 3) */
    Image *accum = image;
    if (what && strstr(what, "irisprep"))
    {
        char name[MAX_PATH];
        get_image_name(image, "irisprep", name);
        save_tiff_luminance(name, accum);
    }
    int hrun = longest_horizontal_run(accum, w * 0.1, 191);
    int vrun = longest_vertical_run(accum, h * 0.1, 191);
    Image *result = canny(accum, 3, 15, 1, 0, what);
    /* threshold_below(result, 7, 0) */
    /* threshold_above(result, 8, 255) */
    threshold_below(result, 6, 0);
    threshold_above(result, 7, 255);
    if (what && strstr(what, "iriscanny"))
    {
        char name[MAX_PATH];
        get_image_name(image, "iriscanny", name);
        save_tiff_luminance(name, result);
    }
    remove_streaks(result, what, 6, 6, 6, 10, 10, 10, 10, 2, 10, False);
    if (what && strstr(what, "irisstreaks"))
    {
        char name[MAX_PATH];
        get_image_name(image, "irisstreaks", name);
        save_tiff_luminance(name, result);
        /* adjust_luminance(result, 1, 1) */
        /* shift_multiply_shift_image(result, 2, 0) */
    }
    int cx = 0, cy = 0, cr = 0;
    int ax, ay, bx, by;
    bounds_bigger_than_threshold(result, 0, &ax, &ay, &bx, &by);
    /* make sure the pupil area is covered */
    /* TODO: in fact, the area to use for the accum (the above) and possible */
    /* iris center should be separated.. */
    if (px - pr < ax)
    {
        ax = px - pr;
    }
    if (py - pr < ay)
    {
        ay = py - pr;
    }
    if (px + pr > bx)
    {
        bx = px + pr;
    }
    if (py - pr > by)
    {
        by = py + pr;
    }
    printf("Iris must be within: %d %d %d %d\n", ax, bx, ay, by);
    if (bx - ax >= min_r && by - ay >= min_r)
    /* FIXME: actually, the area for the "center" is much smaller. There's no */
    /* point to e.g. let it lie outside the pupil */
    {
        int max_r = pr * 8;
        if (max_r > (bx - ax) / 2)
        {
            max_r = (bx - ax) / 2;
            /* No point making the radius bigger than half the biggest run */
        }
        int run = max(hrun, vrun);
        if (max_r > run / 2)
        {
            max_r = run / 2;
            /* OTOH, it shouldn't be too small.. blah.. */
        }
        run = min(hrun, vrun);
        if (max_r < run / 2)
        {
            max_r = run / 2;
        }
        printf("Iris radius assumed to be no more than %d (%d/%d).\n", max_r, hrun, vrun);
        /* Hack: We dim pixels far above the horizontal line through the pupil */
        /* center, since the actual circle outline mostly can contribute from */
        /* the center. */
        /* 240 at double radius */
        dim_above_horizon(result, py, 240.0 / pr / pr / 4);
        if (what && strstr(what, "dimmed"))
        {
            char name[MAX_PATH];
            get_image_name(image, "dimmed", name);
            save_tiff_luminance(name, result);
        }
        Vector *circles = hough_circle(result, min_r, max_r, ax, bx, ay, by, IRIS_HOUGH_THRESHOLD, pr * 1.3, px, py, what, "irisaccums", "irisaccums");
        printf("%d possible circles\n", circles->count);
        int debug = False;
        find_best_circle(circles, &cx, &cy, &cr, 1, px, py, pr, 10, debug);
    }
    Image *rgb = BtoRGB(orig_image);
    Color red = {255, 0, 0};
    draw_location(rgb, px, py, red);
    draw_circle(rgb, px - pr, py - pr, px + pr, py + pr, red);
    Color green = {0, 192, 0};
    draw_location(rgb, cx, cy, green);
    draw_circle(rgb, cx - cr, cy - cr, cx + cr, cy + cr, green);
    *out_ix = cx;
    *out_iy = cy;
    *out_ir = cr;
    return rgb;
}
/* This file was generated by scramble.py. */
