// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -----------------------------------------------------------------------------
//
//  Near-lossless pre-processing
//
// Author: Skal (pascal.massimino@gmail.com)
//

#include "src/dsp/dsp.h"
#include "src/enc/analysis.h"
#include "src/utils/vector.h"

namespace WP2 {

// returns the number of bits to remove (q=99 -> 1bit, q=96 -> 4bit)
static uint32_t NumBitsToRemove(float quality) {
  return (uint32_t)std::min(4.f, std::max(1.f, 100.f - quality));
}

static void BuildMap(uint8_t map[256], uint32_t bits) {
  const uint32_t mask = (1u << bits) - 1;
  for (uint32_t i = 0; i < 256; ++i) {
    const uint32_t biased = i + (mask >> 1) + ((i >> bits) & 1);
    map[i] = (biased > 0xff) ? 0xff : (biased & ~mask);
  }
}

static uint32_t SmoothValue(uint32_t v, const uint8_t map[]) {
  return (map[(v >> 24) & 0xff] << 24) | (map[(v >> 16) & 0xff] << 16) |
         (map[(v >>  8) & 0xff] <<  8) | (map[(v >>  0) & 0xff] <<  0);
}

static bool IsFar(uint32_t a, uint32_t b, int limit) {
  for (uint32_t k = 0; k < 32; k += 8) {
    const int delta =
        (int)((a >> k) & 0xff) - (int)((b >> k) & 0xff);
    if (delta >= limit || delta <= -limit) {
      return true;
    }
  }
  return false;
}

static uint32_t Smooth(const uint32_t* const prev,
                       const uint32_t* const cur,
                       const uint32_t* const next,
                       uint32_t x, uint32_t limit,
                       const uint8_t map[]) {
  uint32_t v = cur[x];
  if (IsFar(v, cur[x - 1], limit) || IsFar(v, cur[x + 1], limit) ||
      IsFar(v, prev[x], limit) || IsFar(v, next[x], limit)) {
    v = SmoothValue(v, map);
  }
  return v;
}

WP2Status PreprocessNearLossless(const ArgbBuffer& in_buffer,
                                 const EncoderConfig& config, bool is_alpha,
                                 ArgbBuffer* const out_buffer) {
  WP2_CHECK_OK(out_buffer != nullptr, WP2_STATUS_INVALID_PARAMETER);
  WP2_CHECK_OK(
      in_buffer.format() == WP2_Argb_32 || in_buffer.format() == WP2_ARGB_32,
      WP2_STATUS_INVALID_COLORSPACE);
  WP2_CHECK_OK(out_buffer->format() == in_buffer.format(),
               WP2_STATUS_INVALID_COLORSPACE);
  const uint32_t w = in_buffer.width(), h = in_buffer.height();
  WP2_CHECK_STATUS(out_buffer->Resize(w, h));
  Vector_u32 tmp;
  WP2_CHECK_ALLOC_OK(tmp.resize(2 * w));   // temporary rotating buffer

  const ArgbBuffer* src = &in_buffer;  // source
  const float quality = is_alpha ? config.alpha_quality : config.quality;
  for (uint32_t bits = NumBitsToRemove(quality); bits > 0; --bits) {
    const uint32_t limit = std::max(1u, ((1u << bits) - 1u) / 2u);
    uint8_t map[256];
    BuildMap(map, bits);  // could be cached per 'bits' value [1..4]
    uint32_t* prev = &tmp[0 * w];
    uint32_t* cur  = &tmp[1 * w];
    const uint32_t* in = (const uint32_t*)src->GetRow(0);
    const uint32_t* in_p = in;
    for (uint32_t y = 0; y < h; ++y) {
      const uint32_t* const in_n =
          (const uint32_t*)src->GetRow(y + 1 < h ? y + 1 : h - 1);
      cur[0] = in[0];
      cur[w - 1] = in[w - 1];
      for (uint32_t x = 1; x + 1 < w; x += 1) {
        cur[x] = Smooth(in_p, in, in_n, x, limit, map);
      }
      if (y > 0) memcpy(out_buffer->GetRow(y - 1), prev, w * sizeof(*prev));
      std::swap(cur, prev);
      in_p = in;
      in = in_n;
    }
    memcpy(out_buffer->GetRow(h - 1), prev, w * sizeof(*prev));
    src = out_buffer;  // use output buffer as source for next passes
  }
  return WP2_STATUS_OK;
}

}  // namespace WP2
