/*
 * Copyright (c) 2016 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 "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"

typedef struct BPNContext {
    const AVClass *class;

    int bitplane;
    int filter;

    int nb_planes;
    int planeheight[4];
    int planewidth[4];
    int depth;
} BPNContext;

#define OFFSET(x) offsetof(BPNContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static const AVOption bitplanenoise_options[] = {
    { "bitplane", "set bit plane to use for measuring noise",  OFFSET(bitplane), AV_OPT_TYPE_INT,  {.i64=1}, 1, 16, FLAGS},
    { "filter",   "show noisy pixels",                         OFFSET(filter),   AV_OPT_TYPE_BOOL, {.i64=0}, 0,  1, FLAGS},
    { NULL }
};

AVFILTER_DEFINE_CLASS(bitplanenoise);

static int query_formats(AVFilterContext *ctx)
{
    static const enum AVPixelFormat pixfmts[] = {
        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P,
        AV_PIX_FMT_YUV440P,
        AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P,
        AV_PIX_FMT_YUVJ440P,
        AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV420P9,
        AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV420P10,
        AV_PIX_FMT_YUV440P10,
        AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12,
        AV_PIX_FMT_YUV440P12,
        AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14,
        AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV420P16,
        AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
        AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16,
        AV_PIX_FMT_NONE
    };

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

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

    s->nb_planes = desc->nb_components;

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

    s->depth = desc->comp[0].depth;

    return 0;
}

#define CHECK_BIT(x, a, b, c) { \
    bit = (((val[(x)] & mask) == (val[(x) + (a)] & mask)) + \
           ((val[(x)] & mask) == (val[(x) + (b)] & mask)) + \
           ((val[(x)] & mask) == (val[(x) + (c)] & mask))) > 1; \
    if (dst) \
        dst[(x)] = factor * bit; \
    stats[plane] += bit; }

static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    BPNContext *s = ctx->priv;
    const int mask = (1 << (s->bitplane - 1));
    const int factor = (1 << s->depth) - 1;
    float stats[4] = { 0 };
    char metabuf[128];
    int plane, y, x, bit;
    AVFrame *out = s->filter ? NULL : in;

    if (!out) {
        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);
    }

    if (s->depth <= 8) {
        for (plane = 0; plane < s->nb_planes; plane++) {
            const int linesize = in->linesize[plane];
            const int dlinesize = out->linesize[plane];
            uint8_t *val = in->data[plane];
            uint8_t *dst = s->filter ? out->data[plane]: NULL;

            for (y = 0; y < s->planeheight[plane] - 1; y++) {
                CHECK_BIT(0, 1, 1 + linesize, linesize)

                for (x = 1; x < s->planewidth[plane] - 1; x++) {
                    CHECK_BIT(x, -1, 1, linesize)
                }

                CHECK_BIT(x, -1, -1 + linesize, linesize)

                val += linesize;
                if (dst)
                    dst += dlinesize;
            }

            CHECK_BIT(0, 1, 1 - linesize, -linesize)

            for (x = 1; x < s->planewidth[plane] - 1; x++) {
                CHECK_BIT(x, -1, 1, -linesize)
            }

            CHECK_BIT(x, -1, -1 - linesize, -linesize)
        }
    } else {
        for (plane = 0; plane < s->nb_planes; plane++) {
            const int linesize = in->linesize[plane] / 2;
            const int dlinesize = out->linesize[plane] / 2;
            uint16_t *val = (uint16_t *)in->data[plane];
            uint16_t *dst = s->filter ? (uint16_t *)out->data[plane] : NULL;

            val = (uint16_t *)in->data[plane];
            for (y = 0; y < s->planeheight[plane] - 1; y++) {
                CHECK_BIT(0, 1, 1 + linesize, linesize)

                for (x = 1; x < s->planewidth[plane] - 1; x++) {
                    CHECK_BIT(x, -1, 1, linesize)
                }

                CHECK_BIT(x, -1, -1 + linesize, linesize)

                val += linesize;
                if (dst)
                    dst += dlinesize;
            }

            CHECK_BIT(0, 1, 1 - linesize, -linesize)

            for (x = 1; x < s->planewidth[plane] - 1; x++) {
                CHECK_BIT(x, -1, 1, -linesize)
            }

            CHECK_BIT(x, -1, -1 -linesize, -linesize)
        }
    }

    for (plane = 0; plane < s->nb_planes; plane++) {
        char key[32];

        stats[plane] /= s->planewidth[plane] * s->planeheight[plane];
        snprintf(key, sizeof(key), "lavfi.bitplanenoise.%d.%d", plane, s->bitplane);
        snprintf(metabuf, sizeof(metabuf), "%f", 1. - 2.* fabs((stats[plane] - 0.5)));
        av_dict_set(&out->metadata, key, metabuf, 0);
    }

    if (out != in)
        av_frame_free(&in);

    return ff_filter_frame(outlink, out);
}

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

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

AVFilter ff_vf_bitplanenoise = {
    .name           = "bitplanenoise",
    .description    = NULL_IF_CONFIG_SMALL("Measure bit plane noise."),
    .priv_size      = sizeof(BPNContext),
    .query_formats  = query_formats,
    .inputs         = inputs,
    .outputs        = outputs,
    .priv_class     = &bitplanenoise_class,
    .flags          = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
};
