/*
 * Copyright (c) 2019 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
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 */

#include "libavutil/avassert.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"

#undef pixel
#if DEPTH == 8
#define pixel uint8_t
#else
#define pixel uint16_t
#endif

#undef htype
#define htype uint16_t

#undef fn
#undef fn2
#undef fn3
#define SHIFT   ((DEPTH + 1) / 2)
#define BINS    (1 << SHIFT)
#define MASK    (BINS - 1)
#define fn3(a,b)   a##_##b
#define fn2(a,b)   fn3(a,b)
#define fn(a)      fn2(a, DEPTH)

#define PICK_COARSE_BIN(x, y) (BINS * (x) + ((y) >> SHIFT))
#define PICK_FINE_BIN(x, y, z) (BINS * ((x) * ((y) >> SHIFT) + (z)) + ((y) & MASK))

static void fn(filter_plane)(AVFilterContext *ctx, const uint8_t *ssrc, int src_linesize,
                             uint8_t *ddst, int dst_linesize, int width, int height,
                             int slice_h_start, int slice_h_end, int jobnr)
{
    MedianContext *s = ctx->priv;
    htype *ccoarse = s->coarse[jobnr];
    htype *cfine = s->fine[jobnr];
    const int radius = s->radius;
    const int radiusV = s->radiusV;
    const int t = s->t;
    const pixel *src = (const pixel *)ssrc;
    pixel *dst = (pixel *)ddst;
    const pixel *srcp;
    const pixel *p;

    src_linesize /= sizeof(pixel);
    dst_linesize /= sizeof(pixel);

    memset(cfine, 0, s->fine_size * sizeof(*cfine));
    memset(ccoarse, 0, s->coarse_size * sizeof(*ccoarse));

    srcp = src + FFMAX(0, slice_h_start - radiusV) * src_linesize;
    if (jobnr == 0) {
        for (int i = 0; i < width; i++) {
            cfine[PICK_FINE_BIN(width, srcp[i], i)] += radiusV + 1;
            ccoarse[PICK_COARSE_BIN(i, srcp[i])] += radiusV + 1;
        }
    }

    srcp = src + FFMAX(0, slice_h_start - radiusV - (jobnr != 0)) * src_linesize;
    for (int i = 0; i < radiusV + (jobnr != 0) * (1 + radiusV); i++) {
        for (int j = 0; j < width; j++) {
            cfine[PICK_FINE_BIN(width, srcp[j], j)]++;
            ccoarse[PICK_COARSE_BIN(j, srcp[j])]++;
        }
        srcp += src_linesize;
    }

    srcp = src;

    for (int i = slice_h_start; i < slice_h_end; i++) {
        htype coarse[BINS] = { 0 };
        htype fine[BINS][BINS] = { { 0 } };
        htype luc[BINS] = { 0 };

        p = srcp + src_linesize * FFMAX(0, i - radiusV - 1);
        for (int j = 0; j < width; j++) {
            cfine[PICK_FINE_BIN(width, p[j], j)]--;
            ccoarse[PICK_COARSE_BIN(j, p[j])]--;
        }

        p = srcp + src_linesize * FFMIN(height - 1, i + radiusV);
        for (int j = 0; j < width; j++) {
            cfine[PICK_FINE_BIN(width, p[j], j)]++;
            ccoarse[PICK_COARSE_BIN(j, p[j])]++;
        }

        s->hmuladd(coarse, &ccoarse[0], radius, BINS);
        for (int j = 0; j < radius; j++)
            s->hadd(coarse, &ccoarse[BINS * j], BINS);
        for (int k = 0; k < BINS; k++)
            s->hmuladd(&fine[k][0], &cfine[BINS * width * k], 2 * radius + 1, BINS);

        for (int j = 0; j < width; j++) {
            int sum = 0, k, b;
            htype *segment;

            s->hadd(coarse, &ccoarse[BINS * FFMIN(j + radius, width - 1)], BINS);

            for (k = 0; k < BINS; k++) {
                sum += coarse[k];
                if (sum > t) {
                    sum -= coarse[k];
                    break;
                }
            }
            av_assert0(k < BINS);

            if (luc[k] <= j - radius) {
                memset(&fine[k], 0, BINS * sizeof(htype));
                for (luc[k] = j - radius; luc[k] < FFMIN(j + radius + 1, width); luc[k]++)
                    s->hadd(fine[k], &cfine[BINS * (width * k + luc[k])], BINS);
                if (luc[k] < j + radius + 1) {
                    s->hmuladd(&fine[k][0], &cfine[BINS * (width * k + width - 1)], j + radius + 1 - width, BINS);
                    luc[k] = j + radius + 1;
                }
            } else {
                for (; luc[k] < j + radius + 1; luc[k]++) {
                    s->hsub(fine[k], &cfine[BINS * (width * k + FFMAX(luc[k] - 2 * radius - 1, 0))], BINS);
                    s->hadd(fine[k], &cfine[BINS * (width * k + FFMIN(luc[k], width - 1))], BINS);
                }
            }

            s->hsub(coarse, &ccoarse[BINS * FFMAX(j - radius, 0)], BINS);

            segment = fine[k];
            for (b = 0; b < BINS; b++) {
                sum += segment[b];
                if (sum > t) {
                    dst[j] = BINS * k + b;
                    break;
                }
            }
            av_assert0(b < BINS);
        }

        dst += dst_linesize;
    }
}
