/*
 * Copyright © 2018, Niklas Haas
 * 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 "config.h"

#include <stdint.h>

#include "dav1d/picture.h"

#include "common.h"
#include "common/intops.h"
#include "common/bitdepth.h"

#include "fg_apply.h"

static void generate_scaling(const int bitdepth,
                             const uint8_t points[][2], const int num,
                             uint8_t scaling[SCALING_SIZE])
{
#if BITDEPTH == 8
    const int shift_x = 0;
#else
    const int shift_x = bitdepth - 8;
#endif
    const int scaling_size = 1 << bitdepth;

    // Fill up the preceding entries with the initial value
    for (int i = 0; i < points[0][0] << shift_x; i++)
        scaling[i] = points[0][1];

    // Linearly interpolate the values in the middle
    for (int i = 0; i < num - 1; i++) {
        const int bx = points[i][0];
        const int by = points[i][1];
        const int ex = points[i+1][0];
        const int ey = points[i+1][1];
        const int dx = ex - bx;
        const int dy = ey - by;
        const int delta = dy * ((0x10000 + (dx >> 1)) / dx);
        for (int x = 0; x < dx; x++) {
            const int v = by + ((x * delta + 0x8000) >> 16);
            scaling[(bx + x) << shift_x] = v;
        }
    }

    // Fill up the remaining entries with the final value
    for (int i = points[num - 1][0] << shift_x; i < scaling_size; i++)
        scaling[i] = points[num - 1][1];

#if BITDEPTH != 8
    const int pad = 1 << shift_x, rnd = pad >> 1;
    for (int i = 0; i < num - 1; i++) {
        const int bx = points[i][0] << shift_x;
        const int ex = points[i+1][0] << shift_x;
        const int dx = ex - bx;
        for (int x = 0; x < dx; x += pad) {
            const int range = scaling[bx + x + pad] - scaling[bx + x];
            for (int n = 1; n < pad; n++) {
                scaling[bx + x + n] = scaling[bx + x] + ((range * n + rnd) >> shift_x);
            }
        }
    }
#endif
}

#ifndef UNIT_TEST
void bitfn(dav1d_apply_grain)(const Dav1dFilmGrainDSPContext *const dsp,
                              Dav1dPicture *const out,
                              Dav1dPicture *const in)
{
    const Dav1dFilmGrainData *const data = &out->frame_hdr->film_grain.data;

    entry grain_lut[3][GRAIN_HEIGHT + 1][GRAIN_WIDTH];
    uint8_t scaling[3][SCALING_SIZE];
#if BITDEPTH != 8
    const int bitdepth_max = (1 << out->p.bpc) - 1;
#endif

    // Generate grain LUTs as needed
    dsp->generate_grain_y(grain_lut[0], data HIGHBD_TAIL_SUFFIX); // always needed
    if (data->num_uv_points[0] || data->chroma_scaling_from_luma)
        dsp->generate_grain_uv[in->p.layout - 1](grain_lut[1], grain_lut[0],
                                                 data, 0 HIGHBD_TAIL_SUFFIX);
    if (data->num_uv_points[1] || data->chroma_scaling_from_luma)
        dsp->generate_grain_uv[in->p.layout - 1](grain_lut[2], grain_lut[0],
                                                 data, 1 HIGHBD_TAIL_SUFFIX);

    // Generate scaling LUTs as needed
    if (data->num_y_points)
        generate_scaling(in->p.bpc, data->y_points, data->num_y_points, scaling[0]);
    if (data->num_uv_points[0])
        generate_scaling(in->p.bpc, data->uv_points[0], data->num_uv_points[0], scaling[1]);
    if (data->num_uv_points[1])
        generate_scaling(in->p.bpc, data->uv_points[1], data->num_uv_points[1], scaling[2]);

    // Copy over the non-modified planes
    // TODO: eliminate in favor of per-plane refs
    assert(out->stride[0] == in->stride[0]);
    if (!data->num_y_points) {
        memcpy(out->data[0], in->data[0], out->p.h * out->stride[0]);
    }

    if (in->p.layout != DAV1D_PIXEL_LAYOUT_I400) {
        assert(out->stride[1] == in->stride[1]);
        for (int i = 0; i < 2; i++) {
            if (!data->num_uv_points[i] && !data->chroma_scaling_from_luma) {
                const int suby = in->p.layout == DAV1D_PIXEL_LAYOUT_I420;
                memcpy(out->data[1+i], in->data[1+i],
                       (out->p.h >> suby) * out->stride[1]);
            }
        }
    }

    // Synthesize grain for the affected planes
    const int rows = (out->p.h + 31) >> 5;
    const int ss_y = in->p.layout == DAV1D_PIXEL_LAYOUT_I420;
    const int ss_x = in->p.layout != DAV1D_PIXEL_LAYOUT_I444;
    const int cpw = (out->p.w + ss_x) >> ss_x;
    const int is_id = out->seq_hdr->mtrx == DAV1D_MC_IDENTITY;
    for (int row = 0; row < rows; row++) {
        pixel *const luma_src =
            ((pixel *) in->data[0]) + row * BLOCK_SIZE * PXSTRIDE(in->stride[0]);

        if (data->num_y_points) {
            const int bh = imin(out->p.h - row * BLOCK_SIZE, BLOCK_SIZE);
            dsp->fgy_32x32xn(((pixel *) out->data[0]) + row * BLOCK_SIZE * PXSTRIDE(out->stride[0]),
                             luma_src, out->stride[0], data,
                             out->p.w, scaling[0], grain_lut[0], bh, row HIGHBD_TAIL_SUFFIX);
        }

        if (!data->num_uv_points[0] && !data->num_uv_points[1] &&
            !data->chroma_scaling_from_luma)
        {
            continue;
        }

        const int bh = (imin(out->p.h - row * BLOCK_SIZE, BLOCK_SIZE) + ss_y) >> ss_y;

        // extend padding pixels
        if (out->p.w & ss_x) {
            pixel *ptr = luma_src;
            for (int y = 0; y < bh; y++) {
                ptr[out->p.w] = ptr[out->p.w - 1];
                ptr += PXSTRIDE(in->stride[0]) << ss_y;
            }
        }

        const ptrdiff_t uv_off = row * BLOCK_SIZE * PXSTRIDE(out->stride[1]) >> ss_y;
        if (data->chroma_scaling_from_luma) {
            for (int pl = 0; pl < 2; pl++)
                dsp->fguv_32x32xn[in->p.layout - 1](((pixel *) out->data[1 + pl]) + uv_off,
                                                    ((const pixel *) in->data[1 + pl]) + uv_off,
                                                    in->stride[1], data, cpw,
                                                    scaling[0], grain_lut[1 + pl],
                                                    bh, row, luma_src, in->stride[0],
                                                    pl, is_id HIGHBD_TAIL_SUFFIX);
        } else {
            for (int pl = 0; pl < 2; pl++)
                if (data->num_uv_points[pl])
                    dsp->fguv_32x32xn[in->p.layout - 1](((pixel *) out->data[1 + pl]) + uv_off,
                                                        ((const pixel *) in->data[1 + pl]) + uv_off,
                                                        in->stride[1], data, cpw,
                                                        scaling[1 + pl], grain_lut[1 + pl],
                                                        bh, row, luma_src, in->stride[0],
                                                        pl, is_id HIGHBD_TAIL_SUFFIX);
        }
    }
}
#endif
