// Copyright 2016 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// MSA variant of alpha filters
//
// Author: Prashant Patil (prashant.patil@imgtec.com)

#include "src/dsp/dsp.h"

#if defined(WEBP_USE_MSA)

#include "src/dsp/msa_macro.h"

#include <assert.h>

static WEBP_INLINE void PredictLineInverse0(const uint8_t* src,
                                            const uint8_t* pred,
                                            uint8_t* dst, int length) {
  v16u8 src0, pred0, dst0;
  assert(length >= 0);
  while (length >= 32) {
    v16u8 src1, pred1, dst1;
    LD_UB2(src, 16, src0, src1);
    LD_UB2(pred, 16, pred0, pred1);
    SUB2(src0, pred0, src1, pred1, dst0, dst1);
    ST_UB2(dst0, dst1, dst, 16);
    src += 32;
    pred += 32;
    dst += 32;
    length -= 32;
  }
  if (length > 0) {
    int i;
    if (length >= 16) {
      src0 = LD_UB(src);
      pred0 = LD_UB(pred);
      dst0 = src0 - pred0;
      ST_UB(dst0, dst);
      src += 16;
      pred += 16;
      dst += 16;
      length -= 16;
    }
    for (i = 0; i < length; i++) {
      dst[i] = src[i] - pred[i];
    }
  }
}

//------------------------------------------------------------------------------
// Helpful macro.

#define SANITY_CHECK(in, out)  \
  assert(in != NULL);          \
  assert(out != NULL);         \
  assert(width > 0);           \
  assert(height > 0);          \
  assert(stride >= width);

//------------------------------------------------------------------------------
// Horrizontal filter

static void HorizontalFilter_MSA(const uint8_t* data, int width, int height,
                                 int stride, uint8_t* filtered_data) {
  const uint8_t* preds = data;
  const uint8_t* in = data;
  uint8_t* out = filtered_data;
  int row = 1;
  SANITY_CHECK(in, out);

  // Leftmost pixel is the same as input for topmost scanline.
  out[0] = in[0];
  PredictLineInverse0(in + 1, preds, out + 1, width - 1);
  preds += stride;
  in += stride;
  out += stride;
  // Filter line-by-line.
  while (row < height) {
    // Leftmost pixel is predicted from above.
    PredictLineInverse0(in, preds - stride, out, 1);
    PredictLineInverse0(in + 1, preds, out + 1, width - 1);
    ++row;
    preds += stride;
    in += stride;
    out += stride;
  }
}

//------------------------------------------------------------------------------
// Gradient filter

static WEBP_INLINE void PredictLineGradient(const uint8_t* pinput,
                                            const uint8_t* ppred,
                                            uint8_t* poutput, int stride,
                                            int size) {
  int w;
  const v16i8 zero = { 0 };
  while (size >= 16) {
    v16u8 pred0, dst0;
    v8i16 a0, a1, b0, b1, c0, c1;
    const v16u8 tmp0 = LD_UB(ppred - 1);
    const v16u8 tmp1 = LD_UB(ppred - stride);
    const v16u8 tmp2 = LD_UB(ppred - stride - 1);
    const v16u8 src0 = LD_UB(pinput);
    ILVRL_B2_SH(zero, tmp0, a0, a1);
    ILVRL_B2_SH(zero, tmp1, b0, b1);
    ILVRL_B2_SH(zero, tmp2, c0, c1);
    ADD2(a0, b0, a1, b1, a0, a1);
    SUB2(a0, c0, a1, c1, a0, a1);
    CLIP_SH2_0_255(a0, a1);
    pred0 = (v16u8)__msa_pckev_b((v16i8)a1, (v16i8)a0);
    dst0 = src0 - pred0;
    ST_UB(dst0, poutput);
    ppred += 16;
    pinput += 16;
    poutput += 16;
    size -= 16;
  }
  for (w = 0; w < size; ++w) {
    const int pred = ppred[w - 1] + ppred[w - stride] - ppred[w - stride - 1];
    poutput[w] = pinput[w] - (pred < 0 ? 0 : pred > 255 ? 255 : pred);
  }
}


static void GradientFilter_MSA(const uint8_t* data, int width, int height,
                               int stride, uint8_t* filtered_data) {
  const uint8_t* in = data;
  const uint8_t* preds = data;
  uint8_t* out = filtered_data;
  int row = 1;
  SANITY_CHECK(in, out);

  // left prediction for top scan-line
  out[0] = in[0];
  PredictLineInverse0(in + 1, preds, out + 1, width - 1);
  preds += stride;
  in += stride;
  out += stride;
  // Filter line-by-line.
  while (row < height) {
    out[0] = in[0] - preds[- stride];
    PredictLineGradient(preds + 1, in + 1, out + 1, stride, width - 1);
    ++row;
    preds += stride;
    in += stride;
    out += stride;
  }
}

//------------------------------------------------------------------------------
// Vertical filter

static void VerticalFilter_MSA(const uint8_t* data, int width, int height,
                               int stride, uint8_t* filtered_data) {
  const uint8_t* in = data;
  const uint8_t* preds = data;
  uint8_t* out = filtered_data;
  int row = 1;
  SANITY_CHECK(in, out);

  // Very first top-left pixel is copied.
  out[0] = in[0];
  // Rest of top scan-line is left-predicted.
  PredictLineInverse0(in + 1, preds, out + 1, width - 1);
  in += stride;
  out += stride;

  // Filter line-by-line.
  while (row < height) {
    PredictLineInverse0(in, preds, out, width);
    ++row;
    preds += stride;
    in += stride;
    out += stride;
  }
}

#undef SANITY_CHECK

//------------------------------------------------------------------------------
// Entry point

extern void VP8FiltersInitMSA(void);

WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitMSA(void) {
  WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter_MSA;
  WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter_MSA;
  WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter_MSA;
}

#else  // !WEBP_USE_MSA

WEBP_DSP_INIT_STUB(VP8FiltersInitMSA)

#endif  // WEBP_USE_MSA
