/*
 * Copyright (c) 2018 Mina Sami
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Color Constancy filter
 *
 * @see http://colorconstancy.com/
 *
 * @cite
 * J. van de Weijer, Th. Gevers, A. Gijsenij "Edge-Based Color Constancy".
 */

#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"

#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"

#include <math.h>

#define GREY_EDGE "greyedge"

#define SQRT3 1.73205080757

#define NUM_PLANES    3
#define MAX_DIFF_ORD  2
#define MAX_META_DATA 4
#define MAX_DATA      4

#define INDEX_TEMP 0
#define INDEX_DX   1
#define INDEX_DY   2
#define INDEX_DXY  3
#define INDEX_NORM INDEX_DX
#define INDEX_SRC  0
#define INDEX_DST  1
#define INDEX_ORD  2
#define INDEX_DIR  3
#define DIR_X 0
#define DIR_Y 1

/**
 * Used for passing data between threads.
 */
typedef struct ThreadData {
    AVFrame *in, *out;
    int meta_data[MAX_META_DATA];
    double  *data[MAX_DATA][NUM_PLANES];
} ThreadData;

/**
 * Common struct for all algorithms contexts.
 */
typedef struct ColorConstancyContext {
    const AVClass *class;

    int difford;
    int minknorm; /**< @minknorm = 0 : getMax instead */
    double sigma;

    int nb_threads;
    int planeheight[4];
    int planewidth[4];

    int filtersize;
    double *gauss[MAX_DIFF_ORD+1];

    double white[NUM_PLANES];
} ColorConstancyContext;

#define OFFSET(x) offsetof(ColorConstancyContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM

#define GINDX(s, i) ( (i) - ((s) >> 2) )

/**
 * Sets gauss filters used for calculating gauss derivatives. Filter size
 * depends on sigma which is a user option hence we calculate these
 * filters each time. Also each higher order depends on lower ones. Sigma
 * can be zero only at difford = 0, then we only convert data to double
 * instead.
 *
 * @param ctx the filter context.
 *
 * @return 0 in case of success, a negative value corresponding to an
 * AVERROR code in case of failure.
 */
static int set_gauss(AVFilterContext *ctx)
{
    ColorConstancyContext *s = ctx->priv;
    int filtersize = s->filtersize;
    int difford    = s->difford;
    double sigma   = s->sigma;
    double sum1, sum2;
    int i;

    for (i = 0; i <= difford; ++i) {
        s->gauss[i] = av_mallocz_array(filtersize, sizeof(*s->gauss[i]));
        if (!s->gauss[i]) {
            for (; i >= 0; --i) {
                av_freep(&s->gauss[i]);
            }
            return AVERROR(ENOMEM);
        }
    }

    // Order 0
    av_log(ctx, AV_LOG_TRACE, "Setting 0-d gauss with filtersize = %d.\n", filtersize);
    sum1 = 0.0;
    if (!sigma) {
        s->gauss[0][0] = 1; // Copying data to double instead of convolution
    } else {
        for (i = 0; i < filtersize; ++i) {
            s->gauss[0][i] = exp(- pow(GINDX(filtersize, i), 2.) / (2 * sigma * sigma)) / ( sqrt(2 * M_PI) * sigma );
            sum1 += s->gauss[0][i];
        }
        for (i = 0; i < filtersize; ++i) {
            s->gauss[0][i] /= sum1;
        }
    }
    // Order 1
    if (difford > 0) {
        av_log(ctx, AV_LOG_TRACE, "Setting 1-d gauss with filtersize = %d.\n", filtersize);
        sum1 = 0.0;
        for (i = 0; i < filtersize; ++i) {
            s->gauss[1][i] = - (GINDX(filtersize, i) / pow(sigma, 2)) * s->gauss[0][i];
            sum1 += s->gauss[1][i] * GINDX(filtersize, i);
        }

        for (i = 0; i < filtersize; ++i) {
            s->gauss[1][i] /= sum1;
        }

        // Order 2
        if (difford > 1) {
            av_log(ctx, AV_LOG_TRACE, "Setting 2-d gauss with filtersize = %d.\n", filtersize);
            sum1 = 0.0;
            for (i = 0; i < filtersize; ++i) {
                s->gauss[2][i] = ( pow(GINDX(filtersize, i), 2) / pow(sigma, 4) - 1/pow(sigma, 2) )
                                 * s->gauss[0][i];
                sum1 += s->gauss[2][i];
            }

            sum2 = 0.0;
            for (i = 0; i < filtersize; ++i) {
                s->gauss[2][i] -= sum1 / (filtersize);
                sum2 += (0.5 * GINDX(filtersize, i) * GINDX(filtersize, i) * s->gauss[2][i]);
            }
            for (i = 0; i < filtersize ; ++i) {
                s->gauss[2][i] /= sum2;
            }
        }
    }
    return 0;
}

/**
 * Frees up buffers used by grey edge for storing derivatives final
 * and intermidiate results. Number of buffers and number of planes
 * for last buffer are given so it can be safely called at allocation
 * failure instances.
 *
 * @param td holds the buffers.
 * @param nb_buff number of buffers to be freed.
 * @param nb_planes number of planes for last buffer to be freed.
 */
static void cleanup_derivative_buffers(ThreadData *td, int nb_buff, int nb_planes)
{
    int b, p;

    for (b = 0; b < nb_buff; ++b) {
        for (p = 0; p < NUM_PLANES; ++p) {
            av_freep(&td->data[b][p]);
        }
    }
    // Final buffer may not be fully allocated at fail cases
    for (p = 0; p < nb_planes; ++p) {
        av_freep(&td->data[b][p]);
    }
}

/**
 * Allocates buffers used by grey edge for storing derivatives final
 * and intermidiate results.
 *
 * @param ctx the filter context.
 * @param td holds the buffers.
 *
 * @return 0 in case of success, a negative value corresponding to an
 * AVERROR code in case of failure.
 */
static int setup_derivative_buffers(AVFilterContext* ctx, ThreadData *td)
{
    ColorConstancyContext *s = ctx->priv;
    int nb_buff = s->difford + 1;
    int b, p;

    av_log(ctx, AV_LOG_TRACE, "Allocating %d buffer(s) for grey edge.\n", nb_buff);
    for (b = 0; b <= nb_buff; ++b) { // We need difford + 1 buffers
        for (p = 0; p < NUM_PLANES; ++p) {
            td->data[b][p] = av_mallocz_array(s->planeheight[p] * s->planewidth[p], sizeof(*td->data[b][p]));
            if (!td->data[b][p]) {
                cleanup_derivative_buffers(td, b + 1, p);
                return AVERROR(ENOMEM);
            }
        }
    }
    return 0;
}

#define CLAMP(x, mx) av_clip((x), 0, (mx-1))
#define INDX2D(r, c, w) ( (r) * (w) + (c) )
#define GAUSS(s, sr, sc, sls, sh, sw, g) ( (s)[ INDX2D(CLAMP((sr), (sh)), CLAMP((sc), (sw)), (sls)) ] * (g) )

/**
 * Slice calculation of gaussian derivatives. Applies 1-D gaussian derivative filter
 * either horizontally or vertically according to meta data given in thread data.
 * When convoluting horizontally source is always the in frame withing thread data
 * while when convoluting vertically source is a buffer.
 *
 * @param ctx the filter context.
 * @param arg data to be passed between threads.
 * @param jobnr current job nubmer.
 * @param nb_jobs total number of jobs.
 *
 * @return 0.
 */
static int slice_get_derivative(AVFilterContext* ctx, void* arg, int jobnr, int nb_jobs)
{
    ColorConstancyContext *s = ctx->priv;
    ThreadData *td = arg;
    AVFrame *in = td->in;
    const int ord = td->meta_data[INDEX_ORD];
    const int dir = td->meta_data[INDEX_DIR];
    const int src_index  = td->meta_data[INDEX_SRC];
    const int dst_index  = td->meta_data[INDEX_DST];
    const int filtersize = s->filtersize;
    const double *gauss  = s->gauss[ord];
    int plane;

    for (plane = 0; plane < NUM_PLANES; ++plane) {
        const int height      = s->planeheight[plane];
        const int width       = s->planewidth[plane];
        const int in_linesize = in->linesize[plane];
        double *dst = td->data[dst_index][plane];
        int slice_start, slice_end;
        int r, c, g;

        if (dir == DIR_X) {
            /** Applying gauss horizontally along each row */
            const uint8_t *src = in->data[plane];
            slice_start = (height * jobnr      ) / nb_jobs;
            slice_end   = (height * (jobnr + 1)) / nb_jobs;

            for (r = slice_start; r < slice_end; ++r) {
                for (c = 0; c < width; ++c) {
                    dst[INDX2D(r, c, width)] = 0;
                    for (g = 0; g < filtersize; ++g) {
                        dst[INDX2D(r, c, width)] += GAUSS(src, r,                        c + GINDX(filtersize, g),
                                                          in_linesize, height, width, gauss[g]);
                    }
                }
            }
        } else {
            /** Applying gauss vertically along each column */
            const double *src = td->data[src_index][plane];
            slice_start = (width * jobnr      ) / nb_jobs;
            slice_end   = (width * (jobnr + 1)) / nb_jobs;

            for (c = slice_start; c < slice_end; ++c) {
                for (r = 0; r < height; ++r) {
                    dst[INDX2D(r, c, width)] = 0;
                    for (g = 0; g < filtersize; ++g) {
                        dst[INDX2D(r, c, width)] += GAUSS(src, r + GINDX(filtersize, g), c,
                                                          width, height, width, gauss[g]);
                    }
                }
            }
        }

    }
    return 0;
}

/**
 * Slice Frobius normalization of gaussian derivatives. Only called for difford values of
 * 1 or 2.
 *
 * @param ctx the filter context.
 * @param arg data to be passed between threads.
 * @param jobnr current job nubmer.
 * @param nb_jobs total number of jobs.
 *
 * @return 0.
 */
static int slice_normalize(AVFilterContext* ctx, void* arg, int jobnr, int nb_jobs)
{
    ColorConstancyContext *s = ctx->priv;
    ThreadData *td = arg;
    const int difford = s->difford;
    int plane;

    for (plane = 0; plane < NUM_PLANES; ++plane) {
        const int height = s->planeheight[plane];
        const int width  = s->planewidth[plane];
        const int64_t numpixels = width * (int64_t)height;
        const int slice_start   = (numpixels * jobnr    ) / nb_jobs;
        const int slice_end     = (numpixels * (jobnr+1)) / nb_jobs;
        const double *dx = td->data[INDEX_DX][plane];
        const double *dy = td->data[INDEX_DY][plane];
        double *norm = td->data[INDEX_NORM][plane];
        int i;

        if (difford == 1) {
            for (i = slice_start; i < slice_end; ++i) {
                norm[i] = sqrt( pow(dx[i], 2) + pow(dy[i], 2));
            }
        } else {
            const double *dxy = td->data[INDEX_DXY][plane];
            for (i = slice_start; i < slice_end; ++i) {
                norm[i] = sqrt( pow(dx[i], 2) + 4 * pow(dxy[i], 2) + pow(dy[i], 2) );
            }
        }
    }

    return 0;
}

/**
 * Utility function for setting up differentiation data/metadata.
 *
 * @param ctx the filter context.
 * @param td to be used for passing data between threads.
 * @param ord ord of differentiation.
 * @param dir direction of differentiation.
 * @param src index of source used for differentiation.
 * @param dst index destination used for saving differentiation result.
 * @param dim maximum dimension in current direction.
 * @param nb_threads number of threads to use.
 */
static void av_always_inline
get_deriv(AVFilterContext *ctx, ThreadData *td, int ord, int dir,
          int src, int dst, int dim, int nb_threads) {
    td->meta_data[INDEX_ORD] = ord;
    td->meta_data[INDEX_DIR] = dir;
    td->meta_data[INDEX_SRC] = src;
    td->meta_data[INDEX_DST] = dst;
    ctx->internal->execute(ctx, slice_get_derivative, td, NULL, FFMIN(dim, nb_threads));
}

/**
 * Main control function for calculating gaussian derivatives.
 *
 * @param ctx the filter context.
 * @param td holds the buffers used for storing results.
 *
 * @return 0 in case of success, a negative value corresponding to an
 * AVERROR code in case of failure.
 */
static int get_derivative(AVFilterContext *ctx, ThreadData *td)
{
    ColorConstancyContext *s = ctx->priv;
    int nb_threads = s->nb_threads;
    int height = s->planeheight[1];
    int width  = s->planewidth[1];

    switch(s->difford) {
    case 0:
        if (!s->sigma) { // Only copy once
            get_deriv(ctx, td, 0, DIR_X, 0         , INDEX_NORM, height, nb_threads);
        } else {
            get_deriv(ctx, td, 0, DIR_X, 0,          INDEX_TEMP, height, nb_threads);
            get_deriv(ctx, td, 0, DIR_Y, INDEX_TEMP, INDEX_NORM, width , nb_threads);
            // save to INDEX_NORM because this will not be normalied and
            // end gry edge filter expects result to be found in INDEX_NORM
        }
        return 0;

    case 1:
        get_deriv(ctx, td, 1, DIR_X, 0,          INDEX_TEMP, height, nb_threads);
        get_deriv(ctx, td, 0, DIR_Y, INDEX_TEMP, INDEX_DX,   width , nb_threads);

        get_deriv(ctx, td, 0, DIR_X, 0,          INDEX_TEMP, height, nb_threads);
        get_deriv(ctx, td, 1, DIR_Y, INDEX_TEMP, INDEX_DY,   width , nb_threads);
        return 0;

    case 2:
        get_deriv(ctx, td, 2, DIR_X, 0,          INDEX_TEMP, height, nb_threads);
        get_deriv(ctx, td, 0, DIR_Y, INDEX_TEMP, INDEX_DX,   width , nb_threads);

        get_deriv(ctx, td, 0, DIR_X, 0,          INDEX_TEMP, height, nb_threads);
        get_deriv(ctx, td, 2, DIR_Y, INDEX_TEMP, INDEX_DY,   width , nb_threads);

        get_deriv(ctx, td, 1, DIR_X, 0,          INDEX_TEMP, height, nb_threads);
        get_deriv(ctx, td, 1, DIR_Y, INDEX_TEMP, INDEX_DXY,  width , nb_threads);
        return 0;

    default:
        av_log(ctx, AV_LOG_ERROR, "Unsupported difford value: %d.\n", s->difford);
        return AVERROR(EINVAL);
    }

}

/**
 * Slice function for grey edge algorithm that does partial summing/maximizing
 * of gaussian derivatives.
 *
 * @param ctx the filter context.
 * @param arg data to be passed between threads.
 * @param jobnr current job nubmer.
 * @param nb_jobs total number of jobs.
 *
 * @return 0.
 */
static int filter_slice_grey_edge(AVFilterContext* ctx, void* arg, int jobnr, int nb_jobs)
{
    ColorConstancyContext *s = ctx->priv;
    ThreadData *td = arg;
    AVFrame *in    = td->in;
    int minknorm   = s->minknorm;
    const uint8_t thresh = 255;
    int plane;

    for (plane = 0; plane < NUM_PLANES; ++plane) {
        const int height        = s->planeheight[plane];
        const int width         = s->planewidth[plane];
        const int in_linesize   = in->linesize[plane];
        const int slice_start   = (height * jobnr) / nb_jobs;
        const int slice_end     = (height * (jobnr+1)) / nb_jobs;
        const uint8_t *img_data = in->data[plane];
        const double *src       = td->data[INDEX_NORM][plane];
        double *dst             = td->data[INDEX_DST][plane];
        int r, c;

        dst[jobnr] = 0;
        if (!minknorm) {
            for (r = slice_start; r < slice_end; ++r) {
                for (c = 0; c < width; ++c) {
                    dst[jobnr] = FFMAX( dst[jobnr], fabs(src[INDX2D(r, c, width)])
                                        * (img_data[INDX2D(r, c, in_linesize)] < thresh) );
                }
            }
        } else {
            for (r = slice_start; r < slice_end; ++r) {
                for (c = 0; c < width; ++c) {
                    dst[jobnr] += ( pow( fabs(src[INDX2D(r, c, width)] / 255.), minknorm)
                                    * (img_data[INDX2D(r, c, in_linesize)] < thresh) );
                }
            }
        }
    }
    return 0;
}

/**
 * Main control function for grey edge algorithm.
 *
 * @param ctx the filter context.
 * @param in frame to perfrom grey edge on.
 *
 * @return 0 in case of success, a negative value corresponding to an
 * AVERROR code in case of failure.
 */
static int filter_grey_edge(AVFilterContext *ctx, AVFrame *in)
{
    ColorConstancyContext *s = ctx->priv;
    ThreadData td;
    int minknorm  = s->minknorm;
    int difford   = s->difford;
    double *white = s->white;
    int nb_jobs   = FFMIN3(s->planeheight[1], s->planewidth[1], s->nb_threads);
    int plane, job, ret;

    td.in = in;
    ret = setup_derivative_buffers(ctx, &td);
    if (ret) {
        return ret;
    }
    get_derivative(ctx, &td);
    if (difford > 0) {
        ctx->internal->execute(ctx, slice_normalize, &td, NULL, nb_jobs);
    }

    ctx->internal->execute(ctx, filter_slice_grey_edge, &td, NULL, nb_jobs);
    if (!minknorm) {
        for (plane = 0; plane < NUM_PLANES; ++plane) {
            white[plane] = 0; // All values are absolute
            for (job = 0; job < nb_jobs; ++job) {
                white[plane] = FFMAX(white[plane] , td.data[INDEX_DST][plane][job]);
            }
        }
    } else {
        for (plane = 0; plane < NUM_PLANES; ++plane) {
            white[plane] = 0;
            for (job = 0; job < nb_jobs; ++job) {
                white[plane] += td.data[INDEX_DST][plane][job];
            }
            white[plane] = pow(white[plane], 1./minknorm);
        }
    }

    cleanup_derivative_buffers(&td, difford + 1, NUM_PLANES);
    return 0;
}

/**
 * Normalizes estimated illumination since only illumination vector
 * direction is required for color constancy.
 *
 * @param light the estimated illumination to be normalized in place
 */
static void normalize_light(double *light)
{
    double abs_val = pow( pow(light[0], 2.0) + pow(light[1], 2.0) + pow(light[2], 2.0), 0.5);
    int plane;

    // TODO: check if setting to 1.0 when estimated = 0.0 is the best thing to do

    if (!abs_val) {
        for (plane = 0; plane < NUM_PLANES; ++plane) {
            light[plane] = 1.0;
        }
    } else {
        for (plane = 0; plane < NUM_PLANES; ++plane) {
            light[plane] = (light[plane] / abs_val);
            if (!light[plane]) { // to avoid division by zero when correcting
                light[plane] = 1.0;
            }
        }
    }
}

/**
 * Redirects to corresponding algorithm estimation function and performs normalization
 * after estimation.
 *
 * @param ctx the filter context.
 * @param in frame to perfrom estimation on.
 *
 * @return 0 in case of success, a negative value corresponding to an
 * AVERROR code in case of failure.
 */
static int illumination_estimation(AVFilterContext *ctx, AVFrame *in)
{
    ColorConstancyContext *s = ctx->priv;
    int ret;

    ret = filter_grey_edge(ctx, in);

    av_log(ctx, AV_LOG_DEBUG, "Estimated illumination= %f %f %f\n",
           s->white[0], s->white[1], s->white[2]);
    normalize_light(s->white);
    av_log(ctx, AV_LOG_DEBUG, "Estimated illumination after normalization= %f %f %f\n",
           s->white[0], s->white[1], s->white[2]);

    return ret;
}

/**
 * Performs simple correction via diagonal transformation model.
 *
 * @param ctx the filter context.
 * @param arg data to be passed between threads.
 * @param jobnr current job nubmer.
 * @param nb_jobs total number of jobs.
 *
 * @return 0.
 */
static int diagonal_transformation(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
    ColorConstancyContext *s = ctx->priv;
    ThreadData *td = arg;
    AVFrame *in = td->in;
    AVFrame *out = td->out;
    int plane;

    for (plane = 0; plane < NUM_PLANES; ++plane) {
        const int height = s->planeheight[plane];
        const int width  = s->planewidth[plane];
        const int64_t numpixels = width * (int64_t)height;
        const int slice_start   = (numpixels * jobnr) / nb_jobs;
        const int slice_end     = (numpixels * (jobnr+1)) / nb_jobs;
        const uint8_t *src = in->data[plane];
        uint8_t *dst       = out->data[plane];
        double temp;
        unsigned i;

        for (i = slice_start; i < slice_end; ++i) {
            temp = src[i] / (s->white[plane] * SQRT3);
            dst[i] = av_clip_uint8((int)(temp + 0.5));
        }
    }
    return 0;
}

/**
 * Main control function for correcting scene illumination based on
 * estimated illumination.
 *
 * @param ctx the filter context.
 * @param in holds frame to correct
 * @param out holds corrected frame
 */
static void chromatic_adaptation(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
{
    ColorConstancyContext *s = ctx->priv;
    ThreadData td;
    int nb_jobs = FFMIN3(s->planeheight[1], s->planewidth[1], s->nb_threads);

    td.in  = in;
    td.out = out;
    ctx->internal->execute(ctx, diagonal_transformation, &td, NULL, nb_jobs);
}

static int query_formats(AVFilterContext *ctx)
{
    static const enum AVPixelFormat pix_fmts[] = {
        // TODO: support more formats
        // FIXME: error when saving to .jpg
        AV_PIX_FMT_GBRP,
        AV_PIX_FMT_NONE
    };

    return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
}

static int config_props(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    ColorConstancyContext *s = ctx->priv;
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
    const double break_off_sigma = 3.0;
    double sigma = s->sigma;
    int ret;

    if (!floor(break_off_sigma * sigma + 0.5) && s->difford) {
        av_log(ctx, AV_LOG_ERROR, "floor(%f * sigma) must be > 0 when difford > 0.\n", break_off_sigma);
        return AVERROR(EINVAL);
    }

    s->filtersize = 2 * floor(break_off_sigma * sigma + 0.5) + 1;
    if (ret=set_gauss(ctx)) {
        return ret;
    }

    s->nb_threads = ff_filter_get_nb_threads(ctx);
    s->planewidth[1]  = s->planewidth[2]  = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
    s->planewidth[0]  = s->planewidth[3]  = inlink->w;
    s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
    s->planeheight[0] = s->planeheight[3] = inlink->h;

    return 0;
}

static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    AVFrame *out;
    int ret;
    int direct = 0;

    ret = illumination_estimation(ctx, in);
    if (ret) {
        av_frame_free(&in);
        return ret;
    }

    if (av_frame_is_writable(in)) {
        direct = 1;
        out = in;
    } else {
        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
        if (!out) {
            av_frame_free(&in);
            return AVERROR(ENOMEM);
        }
        av_frame_copy_props(out, in);
    }
    chromatic_adaptation(ctx, in, out);

    if (!direct)
        av_frame_free(&in);

    return ff_filter_frame(outlink, out);
}

static av_cold void uninit(AVFilterContext *ctx)
{
    ColorConstancyContext *s = ctx->priv;
    int difford = s->difford;
    int i;

    for (i = 0; i <= difford; ++i) {
        av_freep(&s->gauss[i]);
    }
}

static const AVFilterPad colorconstancy_inputs[] = {
    {
        .name         = "default",
        .type         = AVMEDIA_TYPE_VIDEO,
        .config_props = config_props,
        .filter_frame = filter_frame,
    },
    { NULL }
};

static const AVFilterPad colorconstancy_outputs[] = {
    {
        .name = "default",
        .type = AVMEDIA_TYPE_VIDEO,
    },
    { NULL }
};

#if CONFIG_GREYEDGE_FILTER

static const AVOption greyedge_options[] = {
    { "difford",  "set differentiation order", OFFSET(difford),  AV_OPT_TYPE_INT,    {.i64=1}, 0,   2,      FLAGS },
    { "minknorm", "set Minkowski norm",        OFFSET(minknorm), AV_OPT_TYPE_INT,    {.i64=1}, 0,   20,     FLAGS },
    { "sigma",    "set sigma",                 OFFSET(sigma),    AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.0, 1024.0, FLAGS },
    { NULL }
};

AVFILTER_DEFINE_CLASS(greyedge);

AVFilter ff_vf_greyedge = {
    .name          = GREY_EDGE,
    .description   = NULL_IF_CONFIG_SMALL("Estimates scene illumination by grey edge assumption."),
    .priv_size     = sizeof(ColorConstancyContext),
    .priv_class    = &greyedge_class,
    .query_formats = query_formats,
    .uninit        = uninit,
    .inputs        = colorconstancy_inputs,
    .outputs       = colorconstancy_outputs,
    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
};

#endif /* CONFIG_GREY_EDGE_FILTER */
