/*
 * Copyright (c) 2017 Paul B Mahol
 *
 * 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
 */

#include "libavutil/opt.h"
#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"

typedef struct Points {
    uint16_t x, y;
} Points;

typedef struct FloodfillContext {
    const AVClass *class;

    int x, y;
    int s0, s1, s2, s3;
    int d0, d1, d2, d3;

    int back, front;
    Points *points;

    int (*is_same)(AVFrame *frame, int x, int y,
                   unsigned s0, unsigned s1, unsigned s2, unsigned s3);
    void (*set_pixel)(AVFrame *frame, int x, int y,
                      unsigned d0, unsigned d1, unsigned d2, unsigned d3);
    void (*pick_pixel)(AVFrame *frame, int x, int y,
                       int *s0, int *s1, int *s2, int *s3);
} FloodfillContext;

static int is_inside(int x, int y, int w, int h)
{
    if (x >= 0 && x < w && y >= 0 && y < h)
        return 1;
    return 0;
}

static int is_same4(AVFrame *frame, int x, int y,
                    unsigned s0, unsigned s1, unsigned s2, unsigned s3)
{
    unsigned c0 = frame->data[0][y * frame->linesize[0] + x];
    unsigned c1 = frame->data[1][y * frame->linesize[1] + x];
    unsigned c2 = frame->data[2][y * frame->linesize[2] + x];
    unsigned c3 = frame->data[3][y * frame->linesize[3] + x];

    if (s0 == c0 && s1 == c1 && s2 == c2 && s3 == c3)
        return 1;
    return 0;
}

static int is_same4_16(AVFrame *frame, int x, int y,
                       unsigned s0, unsigned s1, unsigned s2, unsigned s3)
{
    unsigned c0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x);
    unsigned c1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x);
    unsigned c2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x);
    unsigned c3 = AV_RN16(frame->data[3] + y * frame->linesize[3] + 2 * x);

    if (s0 == c0 && s1 == c1 && s2 == c2 && s3 == c3)
        return 1;
    return 0;
}

static int is_same3(AVFrame *frame, int x, int y,
                    unsigned s0, unsigned s1, unsigned s2, unsigned s3)
{
    unsigned c0 = frame->data[0][y * frame->linesize[0] + x];
    unsigned c1 = frame->data[1][y * frame->linesize[1] + x];
    unsigned c2 = frame->data[2][y * frame->linesize[2] + x];

    if (s0 == c0 && s1 == c1 && s2 == c2)
        return 1;
    return 0;
}

static int is_same3_16(AVFrame *frame, int x, int y,
                       unsigned s0, unsigned s1, unsigned s2, unsigned s3)
{
    unsigned c0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x);
    unsigned c1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x);
    unsigned c2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x);

    if (s0 == c0 && s1 == c1 && s2 == c2)
        return 1;
    return 0;
}

static int is_same1(AVFrame *frame, int x, int y,
                    unsigned s0, unsigned s1, unsigned s2, unsigned s3)
{
    unsigned c0 = frame->data[0][y * frame->linesize[0] + x];

    if (s0 == c0)
        return 1;
    return 0;
}

static int is_same1_16(AVFrame *frame, int x, int y,
                       unsigned s0, unsigned s1, unsigned s2, unsigned s3)
{
    unsigned c0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x);

    if (s0 == c0)
        return 1;
    return 0;
}

static void set_pixel1(AVFrame *frame, int x, int y,
                       unsigned d0, unsigned d1, unsigned d2, unsigned d3)
{
    frame->data[0][y * frame->linesize[0] + x] = d0;
}

static void set_pixel1_16(AVFrame *frame, int x, int y,
                          unsigned d0, unsigned d1, unsigned d2, unsigned d3)
{
    AV_WN16(frame->data[0] + y * frame->linesize[0] + 2 * x, d0);
}

static void set_pixel3(AVFrame *frame, int x, int y,
                       unsigned d0, unsigned d1, unsigned d2, unsigned d3)
{
    frame->data[0][y * frame->linesize[0] + x] = d0;
    frame->data[1][y * frame->linesize[1] + x] = d1;
    frame->data[2][y * frame->linesize[2] + x] = d2;
}

static void set_pixel3_16(AVFrame *frame, int x, int y,
                          unsigned d0, unsigned d1, unsigned d2, unsigned d3)
{
    AV_WN16(frame->data[0] + y * frame->linesize[0] + 2 * x, d0);
    AV_WN16(frame->data[1] + y * frame->linesize[1] + 2 * x, d1);
    AV_WN16(frame->data[2] + y * frame->linesize[2] + 2 * x, d2);
}

static void set_pixel4(AVFrame *frame, int x, int y,
                       unsigned d0, unsigned d1, unsigned d2, unsigned d3)
{
    frame->data[0][y * frame->linesize[0] + x] = d0;
    frame->data[1][y * frame->linesize[1] + x] = d1;
    frame->data[2][y * frame->linesize[2] + x] = d2;
    frame->data[3][y * frame->linesize[3] + x] = d3;
}

static void set_pixel4_16(AVFrame *frame, int x, int y,
                          unsigned d0, unsigned d1, unsigned d2, unsigned d3)
{
    AV_WN16(frame->data[0] + y * frame->linesize[0] + 2 * x, d0);
    AV_WN16(frame->data[1] + y * frame->linesize[1] + 2 * x, d1);
    AV_WN16(frame->data[2] + y * frame->linesize[2] + 2 * x, d2);
    AV_WN16(frame->data[3] + y * frame->linesize[3] + 2 * x, d3);
}

static void pick_pixel1(AVFrame *frame, int x, int y,
                        int *s0, int *s1, int *s2, int *s3)
{
    if (*s0 < 0)
        *s0 = frame->data[0][y * frame->linesize[0] + x];
}

static void pick_pixel1_16(AVFrame *frame, int x, int y,
                           int *s0, int *s1, int *s2, int *s3)
{
    if (*s0 < 0)
        *s0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x);
}

static void pick_pixel3(AVFrame *frame, int x, int y,
                        int *s0, int *s1, int *s2, int *s3)
{
    if (*s0 < 0)
        *s0 = frame->data[0][y * frame->linesize[0] + x];
    if (*s1 < 0)
        *s1 = frame->data[1][y * frame->linesize[1] + x];
    if (*s2 < 0)
        *s2 = frame->data[2][y * frame->linesize[2] + x];
}

static void pick_pixel3_16(AVFrame *frame, int x, int y,
                           int *s0, int *s1, int *s2, int *s3)
{
    if (*s0 < 0)
        *s0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x);
    if (*s1 < 0)
        *s1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x);
    if (*s2 < 0)
        *s2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x);
}

static void pick_pixel4(AVFrame *frame, int x, int y,
                        int *s0, int *s1, int *s2, int *s3)
{
    if (*s0 < 0)
        *s0 = frame->data[0][y * frame->linesize[0] + x];
    if (*s1 < 0)
        *s1 = frame->data[1][y * frame->linesize[1] + x];
    if (*s2 < 0)
        *s2 = frame->data[2][y * frame->linesize[2] + x];
    if (*s3 < 0)
        *s3 = frame->data[3][y * frame->linesize[3] + x];
}

static void pick_pixel4_16(AVFrame *frame, int x, int y,
                           int *s0, int *s1, int *s2, int *s3)
{
    if (*s0 < 0)
        *s0 = AV_RN16(frame->data[0] + y * frame->linesize[0] + 2 * x);
    if (*s1 < 0)
        *s1 = AV_RN16(frame->data[1] + y * frame->linesize[1] + 2 * x);
    if (*s2 < 0)
        *s2 = AV_RN16(frame->data[2] + y * frame->linesize[2] + 2 * x);
    if (*s3 < 0)
        *s3 = AV_RN16(frame->data[3] + y * frame->linesize[3] + 2 * x);
}

static int config_input(AVFilterLink *inlink)
{
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
    AVFilterContext *ctx = inlink->dst;
    FloodfillContext *s = ctx->priv;
    int nb_planes = av_pix_fmt_count_planes(inlink->format);
    int depth;

    depth = desc->comp[0].depth;
    if (depth == 8) {
        switch (nb_planes) {
        case 1: s->set_pixel  = set_pixel1;
                s->is_same    = is_same1;
                s->pick_pixel = pick_pixel1; break;
        case 3: s->set_pixel  = set_pixel3;
                s->is_same    = is_same3;
                s->pick_pixel = pick_pixel3; break;
        case 4: s->set_pixel  = set_pixel4;
                s->is_same    = is_same4;
                s->pick_pixel = pick_pixel4; break;
       }
    } else {
        switch (nb_planes) {
        case 1: s->set_pixel  = set_pixel1_16;
                s->is_same    = is_same1_16;
                s->pick_pixel = pick_pixel1_16; break;
        case 3: s->set_pixel  = set_pixel3_16;
                s->is_same    = is_same3_16;
                s->pick_pixel = pick_pixel3_16; break;
        case 4: s->set_pixel  = set_pixel4_16;
                s->is_same    = is_same4_16;
                s->pick_pixel = pick_pixel4_16; break;
       }
    }

    s->front = s->back = 0;
    s->points = av_calloc(inlink->w * inlink->h, 4 * sizeof(Points));
    if (!s->points)
        return AVERROR(ENOMEM);

    return 0;
}

static int filter_frame(AVFilterLink *link, AVFrame *frame)
{
    AVFilterContext *ctx = link->dst;
    FloodfillContext *s = ctx->priv;
    const unsigned d0 = s->d0;
    const unsigned d1 = s->d1;
    const unsigned d2 = s->d2;
    const unsigned d3 = s->d3;
    int s0 = s->s0;
    int s1 = s->s1;
    int s2 = s->s2;
    int s3 = s->s3;
    const int w = frame->width;
    const int h = frame->height;
    int ret;

    if (ret = av_frame_make_writable(frame))
        return ret;

    if (is_inside(s->x, s->y, w, h)) {
        s->pick_pixel(frame, s->x, s->y, &s0, &s1, &s2, &s3);

        if (s->is_same(frame, s->x, s->y, s0, s1, s2, s3)) {
            s->points[s->front].x = s->x;
            s->points[s->front].y = s->y;
            s->front++;
        }

        while (s->front > s->back) {
            int x, y;

            s->front--;
            x = s->points[s->front].x;
            y = s->points[s->front].y;

            if (s->is_same(frame, x, y, s0, s1, s2, s3)) {
                s->set_pixel(frame, x, y, d0, d1, d2, d3);

                if (is_inside(x + 1, y, w, h)) {
                    s->points[s->front]  .x = x + 1;
                    s->points[s->front++].y = y;
                }

                if (is_inside(x - 1, y, w, h)) {
                    s->points[s->front]  .x = x - 1;
                    s->points[s->front++].y = y;
                }

                if (is_inside(x, y + 1, w, h)) {
                    s->points[s->front]  .x = x;
                    s->points[s->front++].y = y + 1;
                }

                if (is_inside(x, y - 1, w, h)) {
                    s->points[s->front]  .x = x;
                    s->points[s->front++].y = y - 1;
                }
            }
        }
    }

    return ff_filter_frame(ctx->outputs[0], frame);
}

static av_cold int query_formats(AVFilterContext *ctx)
{
    static const enum AVPixelFormat pixel_fmts[] = {
        AV_PIX_FMT_GRAY8,
        AV_PIX_FMT_YUV444P,
        AV_PIX_FMT_YUVA444P,
        AV_PIX_FMT_GBRP,
        AV_PIX_FMT_GBRP9,
        AV_PIX_FMT_GBRP10,
        AV_PIX_FMT_GBRAP10,
        AV_PIX_FMT_GBRP12,
        AV_PIX_FMT_GBRAP12,
        AV_PIX_FMT_GBRP14,
        AV_PIX_FMT_GBRP16,
        AV_PIX_FMT_GBRAP16,
        AV_PIX_FMT_GBRAP,
        AV_PIX_FMT_YUV444P9,
        AV_PIX_FMT_YUVA444P9,
        AV_PIX_FMT_YUV444P10,
        AV_PIX_FMT_YUVA444P10,
        AV_PIX_FMT_YUV444P12,
        AV_PIX_FMT_YUV444P14,
        AV_PIX_FMT_GRAY16,
        AV_PIX_FMT_YUV444P16,
        AV_PIX_FMT_YUVA444P16,
        AV_PIX_FMT_NONE
    };
    AVFilterFormats *formats;

    formats = ff_make_format_list(pixel_fmts);
    if (!formats)
        return AVERROR(ENOMEM);

    return ff_set_common_formats(ctx, formats);
}

static av_cold void uninit(AVFilterContext *ctx)
{
    FloodfillContext *s = ctx->priv;

    av_freep(&s->points);
}

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

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

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

static const AVOption floodfill_options[] = {
    { "x",  "set pixel x coordinate",             OFFSET(x),  AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS },
    { "y",  "set pixel y coordinate",             OFFSET(y),  AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS },
    { "s0", "set source #0 component value",      OFFSET(s0), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS },
    { "s1", "set source #1 component value",      OFFSET(s1), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS },
    { "s2", "set source #2 component value",      OFFSET(s2), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS },
    { "s3", "set source #3 component value",      OFFSET(s3), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS },
    { "d0", "set destination #0 component value", OFFSET(d0), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS },
    { "d1", "set destination #1 component value", OFFSET(d1), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS },
    { "d2", "set destination #2 component value", OFFSET(d2), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS },
    { "d3", "set destination #3 component value", OFFSET(d3), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS },
    { NULL }
};

AVFILTER_DEFINE_CLASS(floodfill);

AVFilter ff_vf_floodfill = {
    .name          = "floodfill",
    .description   = NULL_IF_CONFIG_SMALL("Fill area with same color with another color."),
    .priv_size     = sizeof(FloodfillContext),
    .priv_class    = &floodfill_class,
    .query_formats = query_formats,
    .uninit        = uninit,
    .inputs        = floodfill_inputs,
    .outputs       = floodfill_outputs,
    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
};
