/*
 * Copyright © 2018, VideoLAN and dav1d authors
 * Copyright © 2018, Two Orioles, LLC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "tests/checkasm/checkasm.h"

#include <string.h>

#include "src/levels.h"
#include "src/loopfilter.h"

static void init_lpf_border(pixel *const dst, const ptrdiff_t stride,
                            int E, int I, int H, const int bitdepth_max)
{
    const int bitdepth_min_8 = bitdepth_from_max(bitdepth_max) - 8;
    const int F = 1 << bitdepth_min_8;
    E <<= bitdepth_min_8;
    I <<= bitdepth_min_8;
    H <<= bitdepth_min_8;

    const int filter_type = rnd() % 4;
    const int edge_diff = rnd() % ((E + 2) * 4) - 2 * (E + 2);
    switch (filter_type) {
    case 0: // random, unfiltered
        for (int i = -8; i < 8; i++)
            dst[i * stride] = rnd() & bitdepth_max;
        break;
    case 1: // long flat
        dst[-8 * stride] = rnd() & bitdepth_max;
        dst[+7 * stride] = rnd() & bitdepth_max;
        dst[+0 * stride] = rnd() & bitdepth_max;
        dst[-1 * stride] = iclip_pixel(dst[+0 * stride] + edge_diff);
        for (int i = 1; i < 7; i++) {
            dst[-(1 + i) * stride] = iclip_pixel(dst[-1 * stride] +
                                                 rnd() % (2 * (F + 1)) - (F + 1));
            dst[+(0 + i) * stride] = iclip_pixel(dst[+0 * stride] +
                                                 rnd() % (2 * (F + 1)) - (F + 1));
        }
        break;
    case 2: // short flat
        for (int i = 4; i < 8; i++) {
            dst[-(1 + i) * stride] = rnd() & bitdepth_max;
            dst[+(0 + i) * stride] = rnd() & bitdepth_max;
        }
        dst[+0 * stride] = rnd() & bitdepth_max;
        dst[-1 * stride] = iclip_pixel(dst[+0 * stride] + edge_diff);
        for (int i = 1; i < 4; i++) {
            dst[-(1 + i) * stride] = iclip_pixel(dst[-1 * stride] +
                                                 rnd() % (2 * (F + 1)) - (F + 1));
            dst[+(0 + i) * stride] = iclip_pixel(dst[+0 * stride] +
                                                 rnd() % (2 * (F + 1)) - (F + 1));
        }
        break;
    case 3: // normal or hev
        for (int i = 4; i < 8; i++) {
            dst[-(1 + i) * stride] = rnd() & bitdepth_max;
            dst[+(0 + i) * stride] = rnd() & bitdepth_max;
        }
        dst[+0 * stride] = rnd() & bitdepth_max;
        dst[-1 * stride] = iclip_pixel(dst[+0 * stride] + edge_diff);
        for (int i = 1; i < 4; i++) {
            dst[-(1 + i) * stride] = iclip_pixel(dst[-(0 + i) * stride] +
                                                 rnd() % (2 * (I + 1)) - (I + 1));
            dst[+(0 + i) * stride] = iclip_pixel(dst[+(i - 1) * stride] +
                                                 rnd() % (2 * (I + 1)) - (I + 1));
        }
        break;
    }
}

static void check_lpf_sb(loopfilter_sb_fn fn, const char *const name,
                         const int n_blks, const int lf_idx,
                         const int is_chroma, const int dir)
{
    ALIGN_STK_32(pixel, c_dst_mem, 128 * 16,);
    ALIGN_STK_32(pixel, a_dst_mem, 128 * 16,);

    declare_func(void, pixel *dst, ptrdiff_t dst_stride, const uint32_t *mask,
                 const uint8_t (*l)[4], ptrdiff_t b4_stride,
                 const Av1FilterLUT *lut, int w HIGHBD_DECL_SUFFIX);

    pixel *a_dst, *c_dst;
    ptrdiff_t stride, b4_stride;
    int w, h;
    if (dir) {
        a_dst = a_dst_mem + 128 * 8;
        c_dst = c_dst_mem + 128 * 8;
        w = 128;
        h = 16;
        b4_stride = 32;
    } else {
        a_dst = a_dst_mem + 8;
        c_dst = c_dst_mem + 8;
        w = 16;
        h = 128;
        b4_stride = 2;
    }
    stride = w * sizeof(pixel);

    Av1FilterLUT lut;
    const int sharp = rnd() & 7;
    for (int level = 0; level < 64; level++) {
        int limit = level;

        if (sharp > 0) {
            limit >>= (sharp + 3) >> 2;
            limit = imin(limit, 9 - sharp);
        }
        limit = imax(limit, 1);

        lut.i[level] = limit;
        lut.e[level] = 2 * (level + 2) + limit;
    }
    lut.sharp[0] = (sharp + 3) >> 2;
    lut.sharp[1] = sharp ? 9 - sharp : 0xff;

    const int n_strengths = is_chroma ? 2 : 3;
    for (int i = 0; i < n_strengths; i++) {
        if (check_func(fn, "%s_w%d_%dbpc", name,
                       is_chroma ? 4 + 2 * i : 4 << i, BITDEPTH))
        {
            uint32_t vmask[4] = { 0 };
            uint8_t l[32 * 2][4];

            for (int j = 0; j < n_blks; j++) {
                const int idx = rnd() % (i + 2);
                if (idx) vmask[idx - 1] |= 1U << j;
                if (dir) {
                    l[j][lf_idx] = rnd() & 63;
                    l[j + 32][lf_idx] = rnd() & 63;
                } else {
                    l[j * 2][lf_idx] = rnd() & 63;
                    l[j * 2 + 1][lf_idx] = rnd() & 63;
                }
            }
#if BITDEPTH == 16
            const int bitdepth_max = rnd() & 1 ? 0x3ff : 0xfff;
#else
            const int bitdepth_max = 0xff;
#endif

            for (int i = 0; i < 4 * n_blks; i++) {
                const int x = i >> 2;
                int L;
                if (dir) {
                    L = l[32 + x][lf_idx] ? l[32 + x][lf_idx] : l[x][lf_idx];
                } else {
                    L = l[2 * x + 1][lf_idx] ? l[2 * x + 1][lf_idx] : l[2 * x][lf_idx];
                }
                init_lpf_border(c_dst + i * (dir ? 1 : 16), dir ? 128 : 1,
                                lut.e[L], lut.i[L], L >> 4, bitdepth_max);
            }
            memcpy(a_dst_mem, c_dst_mem, 128 * sizeof(pixel) * 16);

            call_ref(c_dst, stride,
                     vmask, (const uint8_t(*)[4]) &l[dir ? 32 : 1][lf_idx], b4_stride,
                     &lut, n_blks HIGHBD_TAIL_SUFFIX);
            call_new(a_dst, stride,
                     vmask, (const uint8_t(*)[4]) &l[dir ? 32 : 1][lf_idx], b4_stride,
                     &lut, n_blks HIGHBD_TAIL_SUFFIX);

            checkasm_check_pixel(c_dst_mem, stride, a_dst_mem, stride,
                                 w, h, "dst");
            bench_new(a_dst, stride,
                      vmask, (const uint8_t(*)[4]) &l[dir ? 32 : 1][lf_idx], b4_stride,
                      &lut, n_blks HIGHBD_TAIL_SUFFIX);
        }
    }
    report(name);
}

void bitfn(checkasm_check_loopfilter)(void) {
    Dav1dLoopFilterDSPContext c;

    bitfn(dav1d_loop_filter_dsp_init)(&c);

    check_lpf_sb(c.loop_filter_sb[0][0], "lpf_h_sb_y", 32, 0, 0, 0);
    check_lpf_sb(c.loop_filter_sb[0][1], "lpf_v_sb_y", 32, 1, 0, 1);
    check_lpf_sb(c.loop_filter_sb[1][0], "lpf_h_sb_uv", 16, 2, 1, 0);
    check_lpf_sb(c.loop_filter_sb[1][1], "lpf_v_sb_uv", 16, 2, 1, 1);
}
