/*
 * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
 * Copyright (c) 2011 Stefano Sabatini
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg 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.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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
 * Apply a boxblur filter to the input video.
 * Ported from MPlayer libmpcodecs/vf_boxblur.c.
 */

#include "libavutil/avstring.h"
#include "libavutil/eval.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"

static const char * const var_names[] = {
    "w",
    "h",
    "cw",
    "ch",
    "hsub",
    "vsub",
    NULL
};

enum var_name {
    VAR_W,
    VAR_H,
    VAR_CW,
    VAR_CH,
    VAR_HSUB,
    VAR_VSUB,
    VARS_NB
};

typedef struct {
    int radius;
    int power;
} FilterParam;

typedef struct {
    FilterParam luma_param;
    FilterParam chroma_param;
    FilterParam alpha_param;
    char luma_radius_expr  [256];
    char chroma_radius_expr[256];
    char alpha_radius_expr [256];

    int hsub, vsub;
    int radius[4];
    int power[4];
    uint8_t *temp[2]; ///< temporary buffer used in blur_power()
} BoxBlurContext;

#define Y 0
#define U 1
#define V 2
#define A 3

static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
    BoxBlurContext *boxblur = ctx->priv;
    int e;

    if (!args) {
        av_log(ctx, AV_LOG_ERROR,
               "Filter expects 2 or 4 or 6 arguments, none provided\n");
        return AVERROR(EINVAL);
    }

    e = sscanf(args, "%255[^:]:%d:%255[^:]:%d:%255[^:]:%d",
               boxblur->luma_radius_expr,   &boxblur->luma_param  .power,
               boxblur->chroma_radius_expr, &boxblur->chroma_param.power,
               boxblur->alpha_radius_expr,  &boxblur->alpha_param .power);

    if (e != 2 && e != 4 && e != 6) {
        av_log(ctx, AV_LOG_ERROR,
               "Filter expects 2 or 4 or 6 params, provided %d\n", e);
        return AVERROR(EINVAL);
    }

    if (e < 4) {
        boxblur->chroma_param.power = boxblur->luma_param.power;
        av_strlcpy(boxblur->chroma_radius_expr, boxblur->luma_radius_expr,
                   sizeof(boxblur->chroma_radius_expr));
    }
    if (e < 6) {
        boxblur->alpha_param.power = boxblur->luma_param.power;
        av_strlcpy(boxblur->alpha_radius_expr, boxblur->luma_radius_expr,
                   sizeof(boxblur->alpha_radius_expr));
    }

    return 0;
}

static av_cold void uninit(AVFilterContext *ctx)
{
    BoxBlurContext *boxblur = ctx->priv;

    av_freep(&boxblur->temp[0]);
    av_freep(&boxblur->temp[1]);
}

static int query_formats(AVFilterContext *ctx)
{
    enum PixelFormat pix_fmts[] = {
        PIX_FMT_YUV444P,  PIX_FMT_YUV422P,  PIX_FMT_YUV420P,
        PIX_FMT_YUV411P,  PIX_FMT_YUV410P,  PIX_FMT_YUVA420P,
        PIX_FMT_YUV440P,  PIX_FMT_GRAY8,
        PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P,
        PIX_FMT_YUVJ440P,
        PIX_FMT_NONE
    };

    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
    return 0;
}

static int config_input(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    BoxBlurContext *boxblur = ctx->priv;
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
    int w = inlink->w, h = inlink->h;
    int cw, ch;
    double var_values[VARS_NB], res;
    char *expr;
    int ret;

    if (!(boxblur->temp[0] = av_malloc(FFMAX(w, h))) ||
        !(boxblur->temp[1] = av_malloc(FFMAX(w, h))))
        return AVERROR(ENOMEM);

    boxblur->hsub = desc->log2_chroma_w;
    boxblur->vsub = desc->log2_chroma_h;

    var_values[VAR_W]  = inlink->w;
    var_values[VAR_H]  = inlink->h;
    var_values[VAR_CW] = cw = w>>boxblur->hsub;
    var_values[VAR_CH] = ch = h>>boxblur->vsub;
    var_values[VAR_HSUB] = 1<<boxblur->hsub;
    var_values[VAR_VSUB] = 1<<boxblur->vsub;

#define EVAL_RADIUS_EXPR(comp)                                          \
    expr = boxblur->comp##_radius_expr;                                 \
    ret = av_expr_parse_and_eval(&res, expr, var_names, var_values,     \
                                 NULL, NULL, NULL, NULL, NULL, 0, ctx); \
    boxblur->comp##_param.radius = res;                                 \
    if (ret < 0) {                                                      \
        av_log(NULL, AV_LOG_ERROR,                                      \
               "Error when evaluating " #comp " radius expression '%s'\n", expr); \
        return ret;                                                     \
    }
    EVAL_RADIUS_EXPR(luma);
    EVAL_RADIUS_EXPR(chroma);
    EVAL_RADIUS_EXPR(alpha);

    av_log(ctx, AV_LOG_INFO,
           "luma_radius:%d luma_power:%d "
           "chroma_radius:%d chroma_power:%d "
           "alpha_radius:%d alpha_power:%d "
           "w:%d chroma_w:%d h:%d chroma_h:%d\n",
           boxblur->luma_param  .radius, boxblur->luma_param  .power,
           boxblur->chroma_param.radius, boxblur->chroma_param.power,
           boxblur->alpha_param .radius, boxblur->alpha_param .power,
           w, cw, h, ch);

#define CHECK_RADIUS_VAL(w_, h_, comp)                                  \
    if (boxblur->comp##_param.radius < 0 ||                             \
        2*boxblur->comp##_param.radius > FFMIN(w_, h_)) {               \
        av_log(ctx, AV_LOG_ERROR,                                       \
               "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \
               boxblur->comp##_param.radius, FFMIN(w_, h_)/2);          \
        return AVERROR(EINVAL);                                         \
    }
    CHECK_RADIUS_VAL(w,  h,  luma);
    CHECK_RADIUS_VAL(cw, ch, chroma);
    CHECK_RADIUS_VAL(w,  h,  alpha);

    boxblur->radius[Y] = boxblur->luma_param.radius;
    boxblur->radius[U] = boxblur->radius[V] = boxblur->chroma_param.radius;
    boxblur->radius[A] = boxblur->alpha_param.radius;

    boxblur->power[Y] = boxblur->luma_param.power;
    boxblur->power[U] = boxblur->power[V] = boxblur->chroma_param.power;
    boxblur->power[A] = boxblur->alpha_param.power;

    return 0;
}

static inline void blur(uint8_t *dst, int dst_step, const uint8_t *src, int src_step,
                        int len, int radius)
{
    /* Naive boxblur would sum source pixels from x-radius .. x+radius
     * for destination pixel x. That would be O(radius*width).
     * If you now look at what source pixels represent 2 consecutive
     * output pixels, then you see they are almost identical and only
     * differ by 2 pixels, like:
     * src0       111111111
     * dst0           1
     * src1        111111111
     * dst1            1
     * src0-src1  1       -1
     * so when you know one output pixel you can find the next by just adding
     * and subtracting 1 input pixel.
     * The following code adopts this faster variant.
     */
    int x, sum = 0;
    const int length = radius*2 + 1;
    const int inv = ((1<<16) + length/2)/length;

    for (x = 0; x < radius; x++)
        sum += src[x*src_step]<<1;
    sum += src[radius*src_step];

    for (x = 0; x <= radius; x++) {
        sum += src[(radius+x)*src_step] - src[(radius-x)*src_step];
        dst[x*dst_step] = (sum*inv + (1<<15))>>16;
    }

    for (; x < len-radius; x++) {
        sum += src[(radius+x)*src_step] - src[(x-radius-1)*src_step];
        dst[x*dst_step] = (sum*inv + (1<<15))>>16;
    }

    for (; x < len; x++) {
        sum += src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step];
        dst[x*dst_step] = (sum*inv + (1<<15))>>16;
    }
}

static inline void blur_power(uint8_t *dst, int dst_step, const uint8_t *src, int src_step,
                              int len, int radius, int power, uint8_t *temp[2])
{
    uint8_t *a = temp[0], *b = temp[1];

    if (radius && power) {
        blur(a, 1, src, src_step, len, radius);
        for (; power > 2; power--) {
            uint8_t *c;
            blur(b, 1, a, 1, len, radius);
            c = a; a = b; b = c;
        }
        if (power > 1) {
            blur(dst, dst_step, a, 1, len, radius);
        } else {
            int i;
            for (i = 0; i < len; i++)
                dst[i*dst_step] = a[i];
        }
    } else {
        int i;
        for (i = 0; i < len; i++)
            dst[i*dst_step] = src[i*src_step];
    }
}

static void hblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize,
                  int w, int h, int radius, int power, uint8_t *temp[2])
{
    int y;

    if (radius == 0 && dst == src)
        return;

    for (y = 0; y < h; y++)
        blur_power(dst + y*dst_linesize, 1, src + y*src_linesize, 1,
                   w, radius, power, temp);
}

static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize,
                  int w, int h, int radius, int power, uint8_t *temp[2])
{
    int x;

    if (radius == 0 && dst == src)
        return;

    for (x = 0; x < w; x++)
        blur_power(dst + x, dst_linesize, src + x, src_linesize,
                   h, radius, power, temp);
}

static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { }

static void end_frame(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    BoxBlurContext *boxblur = ctx->priv;
    AVFilterLink *outlink = inlink->dst->outputs[0];
    AVFilterBufferRef *inpicref  = inlink ->cur_buf;
    AVFilterBufferRef *outpicref = outlink->out_buf;
    int plane;
    int cw = inlink->w >> boxblur->hsub, ch = inlink->h >> boxblur->vsub;
    int w[4] = { inlink->w, cw, cw, inlink->w };
    int h[4] = { inlink->h, ch, ch, inlink->h };

    for (plane = 0; inpicref->data[plane] && plane < 4; plane++)
        hblur(outpicref->data[plane], outpicref->linesize[plane],
              inpicref ->data[plane], inpicref ->linesize[plane],
              w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
              boxblur->temp);

    for (plane = 0; inpicref->data[plane] && plane < 4; plane++)
        vblur(outpicref->data[plane], outpicref->linesize[plane],
              outpicref->data[plane], outpicref->linesize[plane],
              w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
              boxblur->temp);

    avfilter_draw_slice(outlink, 0, inlink->h, 1);
    avfilter_default_end_frame(inlink);
}

AVFilter avfilter_vf_boxblur = {
    .name          = "boxblur",
    .description   = NULL_IF_CONFIG_SMALL("Blur the input."),
    .priv_size     = sizeof(BoxBlurContext),
    .init          = init,
    .uninit        = uninit,
    .query_formats = query_formats,

    .inputs    = (const AVFilterPad[]) {{ .name       = "default",
                                    .type             = AVMEDIA_TYPE_VIDEO,
                                    .config_props     = config_input,
                                    .draw_slice       = null_draw_slice,
                                    .end_frame        = end_frame,
                                    .min_perms        = AV_PERM_READ },
                                  { .name = NULL}},
    .outputs   = (const AVFilterPad[]) {{ .name       = "default",
                                    .type             = AVMEDIA_TYPE_VIDEO, },
                                  { .name = NULL}},
};
