/*
 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
 * Copyright (c) 2014 Arwa Arif <arwaarif1994@gmail.com>
 *
 * 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
 * Postprocessing filter - 7
 *
 * Originally written by Michael Niedermayer for the MPlayer
 * project, and ported by Arwa Arif for FFmpeg.
 */

#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "internal.h"
#include "vf_pp7.h"

enum mode {
    MODE_HARD,
    MODE_SOFT,
    MODE_MEDIUM
};

#define OFFSET(x) offsetof(PP7Context, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static const AVOption pp7_options[] = {
    { "qp", "force a constant quantizer parameter", OFFSET(qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 64, FLAGS },
    { "mode", "set thresholding mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MODE_MEDIUM}, 0, 2, FLAGS, "mode" },
        { "hard",   "hard thresholding",   0, AV_OPT_TYPE_CONST, {.i64 = MODE_HARD},   INT_MIN, INT_MAX, FLAGS, "mode" },
        { "soft",   "soft thresholding",   0, AV_OPT_TYPE_CONST, {.i64 = MODE_SOFT},   INT_MIN, INT_MAX, FLAGS, "mode" },
        { "medium", "medium thresholding", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_MEDIUM}, INT_MIN, INT_MAX, FLAGS, "mode" },
    { NULL }
};

AVFILTER_DEFINE_CLASS(pp7);

DECLARE_ALIGNED(8, static const uint8_t, dither)[8][8] = {
    {  0,  48,  12,  60,   3,  51,  15,  63, },
    { 32,  16,  44,  28,  35,  19,  47,  31, },
    {  8,  56,   4,  52,  11,  59,   7,  55, },
    { 40,  24,  36,  20,  43,  27,  39,  23, },
    {  2,  50,  14,  62,   1,  49,  13,  61, },
    { 34,  18,  46,  30,  33,  17,  45,  29, },
    { 10,  58,   6,  54,   9,  57,   5,  53, },
    { 42,  26,  38,  22,  41,  25,  37,  21, },
};

#define N0 4
#define N1 5
#define N2 10
#define SN0 2
#define SN1 2.2360679775
#define SN2 3.16227766017
#define N (1 << 16)

static const int factor[16] = {
    N / (N0 * N0), N / (N0 * N1), N / (N0 * N0), N / (N0 * N2),
    N / (N1 * N0), N / (N1 * N1), N / (N1 * N0), N / (N1 * N2),
    N / (N0 * N0), N / (N0 * N1), N / (N0 * N0), N / (N0 * N2),
    N / (N2 * N0), N / (N2 * N1), N / (N2 * N0), N / (N2 * N2),
};

static void init_thres2(PP7Context *p)
{
    int qp, i;
    int bias = 0; //FIXME

    for (qp = 0; qp < 99; qp++) {
        for (i = 0; i < 16; i++) {
            p->thres2[qp][i] = ((i&1) ? SN2 : SN0) * ((i&4) ? SN2 : SN0) * FFMAX(1, qp) * (1<<2) - 1 - bias;
        }
    }
}

static inline void dctA_c(int16_t *dst, uint8_t *src, int stride)
{
    int i;

    for (i = 0; i < 4; i++) {
        int s0 = src[0 * stride] + src[6 * stride];
        int s1 = src[1 * stride] + src[5 * stride];
        int s2 = src[2 * stride] + src[4 * stride];
        int s3 = src[3 * stride];
        int s = s3 + s3;
        s3 = s  - s0;
        s0 = s  + s0;
        s  = s2 + s1;
        s2 = s2 - s1;
        dst[0] = s0 + s;
        dst[2] = s0 - s;
        dst[1] = 2 * s3 +     s2;
        dst[3] =     s3 - 2 * s2;
        src++;
        dst += 4;
    }
}

static void dctB_c(int16_t *dst, int16_t *src)
{
    int i;

    for (i = 0; i < 4; i++) {
        int s0 = src[0 * 4] + src[6 * 4];
        int s1 = src[1 * 4] + src[5 * 4];
        int s2 = src[2 * 4] + src[4 * 4];
        int s3 = src[3 * 4];
        int s = s3 + s3;
        s3 = s  - s0;
        s0 = s  + s0;
        s  = s2 + s1;
        s2 = s2 - s1;
        dst[0 * 4] = s0 + s;
        dst[2 * 4] = s0 - s;
        dst[1 * 4] = 2 * s3 +     s2;
        dst[3 * 4] =     s3 - 2 * s2;
        src++;
        dst++;
    }
}

static int hardthresh_c(PP7Context *p, int16_t *src, int qp)
{
    int i;
    int a;

    a = src[0] * factor[0];
    for (i = 1; i < 16; i++) {
        unsigned int threshold1 = p->thres2[qp][i];
        unsigned int threshold2 = threshold1 << 1;
        int level = src[i];
        if (((unsigned)(level + threshold1)) > threshold2)
            a += level * factor[i];
    }
    return (a + (1 << 11)) >> 12;
}

static int mediumthresh_c(PP7Context *p, int16_t *src, int qp)
{
    int i;
    int a;

    a = src[0] * factor[0];
    for (i = 1; i < 16; i++) {
        unsigned int threshold1 = p->thres2[qp][i];
        unsigned int threshold2 = threshold1 << 1;
        int level = src[i];
        if (((unsigned)(level + threshold1)) > threshold2) {
            if (((unsigned)(level + 2 * threshold1)) > 2 * threshold2)
                a += level * factor[i];
            else {
                if (level > 0)
                    a += 2 * (level - (int)threshold1) * factor[i];
                else
                    a += 2 * (level + (int)threshold1) * factor[i];
            }
        }
    }
    return (a + (1 << 11)) >> 12;
}

static int softthresh_c(PP7Context *p, int16_t *src, int qp)
{
    int i;
    int a;

    a = src[0] * factor[0];
    for (i = 1; i < 16; i++) {
        unsigned int threshold1 = p->thres2[qp][i];
        unsigned int threshold2 = threshold1 << 1;
        int level = src[i];
        if (((unsigned)(level + threshold1)) > threshold2) {
            if (level > 0)
                a += (level - (int)threshold1) * factor[i];
            else
                a += (level + (int)threshold1) * factor[i];
        }
    }
    return (a + (1 << 11)) >> 12;
}

static void filter(PP7Context *p, uint8_t *dst, uint8_t *src,
                   int dst_stride, int src_stride,
                   int width, int height,
                   uint8_t *qp_store, int qp_stride, int is_luma)
{
    int x, y;
    const int stride = is_luma ? p->temp_stride : ((width + 16 + 15) & (~15));
    uint8_t *p_src = p->src + 8 * stride;
    int16_t *block = (int16_t *)p->src;
    int16_t *temp  = (int16_t *)(p->src + 32);

    if (!src || !dst) return;
    for (y = 0; y < height; y++) {
        int index = 8 + 8 * stride + y * stride;
        memcpy(p_src + index, src + y * src_stride, width);
        for (x = 0; x < 8; x++) {
            p_src[index         - x - 1]= p_src[index +         x    ];
            p_src[index + width + x    ]= p_src[index + width - x - 1];
        }
    }
    for (y = 0; y < 8; y++) {
        memcpy(p_src + (    7 - y     ) * stride, p_src + (    y + 8     ) * stride, stride);
        memcpy(p_src + (height + 8 + y) * stride, p_src + (height - y + 7) * stride, stride);
    }
    //FIXME (try edge emu)

    for (y = 0; y < height; y++) {
        for (x = -8; x < 0; x += 4) {
            const int index = x + y * stride + (8 - 3) * (1 + stride) + 8; //FIXME silly offset
            uint8_t *src  = p_src + index;
            int16_t *tp   = temp + 4 * x;

            dctA_c(tp + 4 * 8, src, stride);
        }
        for (x = 0; x < width; ) {
            const int qps = 3 + is_luma;
            int qp;
            int end = FFMIN(x + 8, width);

            if (p->qp)
                qp = p->qp;
            else {
                qp = qp_store[ (FFMIN(x, width - 1) >> qps) + (FFMIN(y, height - 1) >> qps) * qp_stride];
                qp = ff_norm_qscale(qp, p->qscale_type);
            }
            for (; x < end; x++) {
                const int index = x + y * stride + (8 - 3) * (1 + stride) + 8; //FIXME silly offset
                uint8_t *src = p_src + index;
                int16_t *tp  = temp + 4 * x;
                int v;

                if ((x & 3) == 0)
                    dctA_c(tp + 4 * 8, src, stride);

                p->dctB(block, tp);

                v = p->requantize(p, block, qp);
                v = (v + dither[y & 7][x & 7]) >> 6;
                if ((unsigned)v > 255)
                    v = (-v) >> 31;
                dst[x + y * dst_stride] = v;
            }
        }
    }
}

static int query_formats(AVFilterContext *ctx)
{
    static const enum AVPixelFormat pix_fmts[] = {
        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P,
        AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV411P,
        AV_PIX_FMT_YUV410P,  AV_PIX_FMT_YUV440P,
        AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ440P,
        AV_PIX_FMT_GBRP,
        AV_PIX_FMT_GRAY8,    AV_PIX_FMT_NONE
    };

    AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
    if (!fmts_list)
        return AVERROR(ENOMEM);
    return ff_set_common_formats(ctx, fmts_list);
}

static int config_input(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;
    PP7Context *pp7 = ctx->priv;
    const int h = FFALIGN(inlink->h + 16, 16);
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);

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

    pp7->temp_stride = FFALIGN(inlink->w + 16, 16);
    pp7->src = av_malloc_array(pp7->temp_stride,  (h + 8) * sizeof(uint8_t));

    if (!pp7->src)
        return AVERROR(ENOMEM);

    init_thres2(pp7);

    switch (pp7->mode) {
        case 0: pp7->requantize = hardthresh_c; break;
        case 1: pp7->requantize = softthresh_c; break;
        default:
        case 2: pp7->requantize = mediumthresh_c; break;
    }

    pp7->dctB = dctB_c;

    if (ARCH_X86)
        ff_pp7_init_x86(pp7);

    return 0;
}

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

    int qp_stride = 0;
    uint8_t *qp_table = NULL;

    if (!pp7->qp)
        qp_table = av_frame_get_qp_table(in, &qp_stride, &pp7->qscale_type);

    if (!ctx->is_disabled) {
        const int cw = AV_CEIL_RSHIFT(inlink->w, pp7->hsub);
        const int ch = AV_CEIL_RSHIFT(inlink->h, pp7->vsub);

        /* get a new frame if in-place is not possible or if the dimensions
        * are not multiple of 8 */
        if (!av_frame_is_writable(in) || (inlink->w & 7) || (inlink->h & 7)) {
            const int aligned_w = FFALIGN(inlink->w, 8);
            const int aligned_h = FFALIGN(inlink->h, 8);

            out = ff_get_video_buffer(outlink, aligned_w, aligned_h);
            if (!out) {
                av_frame_free(&in);
                return AVERROR(ENOMEM);
            }
            av_frame_copy_props(out, in);
            out->width = in->width;
            out->height = in->height;
        }

        if (qp_table || pp7->qp) {

            filter(pp7, out->data[0], in->data[0], out->linesize[0], in->linesize[0],
                   inlink->w, inlink->h, qp_table, qp_stride, 1);
            filter(pp7, out->data[1], in->data[1], out->linesize[1], in->linesize[1],
                   cw,        ch,        qp_table, qp_stride, 0);
            filter(pp7, out->data[2], in->data[2], out->linesize[2], in->linesize[2],
                   cw,        ch,        qp_table, qp_stride, 0);
            emms_c();
        }
    }

    if (in != out) {
        if (in->data[3])
            av_image_copy_plane(out->data[3], out->linesize[3],
                                in ->data[3], in ->linesize[3],
                                inlink->w, inlink->h);
        av_frame_free(&in);
    }
    return ff_filter_frame(outlink, out);
}

static av_cold void uninit(AVFilterContext *ctx)
{
    PP7Context *pp7 = ctx->priv;
    av_freep(&pp7->src);
}

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

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

AVFilter ff_vf_pp7 = {
    .name            = "pp7",
    .description     = NULL_IF_CONFIG_SMALL("Apply Postprocessing 7 filter."),
    .priv_size       = sizeof(PP7Context),
    .uninit          = uninit,
    .query_formats   = query_formats,
    .inputs          = pp7_inputs,
    .outputs         = pp7_outputs,
    .priv_class      = &pp7_class,
    .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
};
