/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */
#include "av1/common/clpf.h"
#include "aom_dsp/aom_dsp_common.h"

int av1_clpf_maxbits(const AV1_COMMON *cm) {
  return get_msb(ALIGN_POWER_OF_TWO(cm->mi_cols * MI_BLOCK_SIZE,
                                    cm->clpf_size + 4) *
                     ALIGN_POWER_OF_TWO(cm->mi_rows * MI_BLOCK_SIZE,
                                        cm->clpf_size + 4) >>
                 (cm->clpf_size * 2 + 8)) +
         1;
}

int av1_clpf_sample(int X, int A, int B, int C, int D, int E, int F, int b) {
  int delta = 4 * clamp(A - X, -b, b) + clamp(B - X, -b, b) +
              3 * clamp(C - X, -b, b) + 3 * clamp(D - X, -b, b) +
              clamp(E - X, -b, b) + 4 * clamp(F - X, -b, b);
  return (8 + delta - (delta < 0)) >> 4;
}

static void clpf_block(const uint8_t *src, uint8_t *dst, int stride, int x0,
                       int y0, int sizex, int sizey, int width, int height,
                       unsigned int strength) {
  int x, y;
  for (y = y0; y < y0 + sizey; y++) {
    for (x = x0; x < x0 + sizex; x++) {
      int X = src[y * stride + x];
      int A = src[AOMMAX(0, y - 1) * stride + x];
      int B = src[y * stride + AOMMAX(0, x - 2)];
      int C = src[y * stride + AOMMAX(0, x - 1)];
      int D = src[y * stride + AOMMIN(width - 1, x + 1)];
      int E = src[y * stride + AOMMIN(width - 1, x + 2)];
      int F = src[AOMMIN(height - 1, y + 1) * stride + x];
      int delta;
      delta = av1_clpf_sample(X, A, B, C, D, E, F, strength);
      dst[y * stride + x] = X + delta;
    }
  }
}

// Return number of filtered blocks
int av1_clpf_frame(const YV12_BUFFER_CONFIG *dst, const YV12_BUFFER_CONFIG *rec,
                   const YV12_BUFFER_CONFIG *org, const AV1_COMMON *cm,
                   int enable_fb_flag, unsigned int strength,
                   unsigned int fb_size_log2, uint8_t *blocks,
                   int (*decision)(int, int, const YV12_BUFFER_CONFIG *,
                                   const YV12_BUFFER_CONFIG *,
                                   const AV1_COMMON *cm, int, int, int,
                                   unsigned int, unsigned int, uint8_t *)) {
  /* Constrained low-pass filter (CLPF) */
  int c, k, l, m, n;
  int width = rec->y_crop_width;
  int height = rec->y_crop_height;
  int xpos, ypos;
  int stride_y = rec->y_stride;
  int stride_c = rec->uv_stride;
  const int bs = MI_BLOCK_SIZE;
  int num_fb_hor = (width + (1 << fb_size_log2) - bs) >> fb_size_log2;
  int num_fb_ver = (height + (1 << fb_size_log2) - bs) >> fb_size_log2;
  int block_index = 0;

  // Iterate over all filter blocks
  for (k = 0; k < num_fb_ver; k++) {
    for (l = 0; l < num_fb_hor; l++) {
      int h, w;
      int allskip = 1;
      for (m = 0; allskip && m < (1 << fb_size_log2) / bs; m++) {
        for (n = 0; allskip && n < (1 << fb_size_log2) / bs; n++) {
          xpos = (l << fb_size_log2) + n * bs;
          ypos = (k << fb_size_log2) + m * bs;
          if (xpos < width && ypos < height) {
            allskip &=
                cm->mi_grid_visible[ypos / bs * cm->mi_stride + xpos / bs]
                    ->mbmi.skip;
          }
        }
      }

      // Calculate the actual filter block size near frame edges
      h = AOMMIN(height, (k + 1) << fb_size_log2) & ((1 << fb_size_log2) - 1);
      w = AOMMIN(width, (l + 1) << fb_size_log2) & ((1 << fb_size_log2) - 1);
      h += !h << fb_size_log2;
      w += !w << fb_size_log2;
      if (!allskip &&  // Do not filter the block if all is skip encoded
          (!enable_fb_flag ||
           decision(k, l, rec, org, cm, bs, w / bs, h / bs, strength,
                    fb_size_log2, blocks + block_index))) {
        // Iterate over all smaller blocks inside the filter block
        for (m = 0; m < (h + bs - 1) / bs; m++) {
          for (n = 0; n < (w + bs - 1) / bs; n++) {
            xpos = (l << fb_size_log2) + n * bs;
            ypos = (k << fb_size_log2) + m * bs;
            if (!cm->mi_grid_visible[ypos / bs * cm->mi_stride + xpos / bs]
                     ->mbmi.skip) {
              // Not skip block, apply the filter
              clpf_block(rec->y_buffer, dst->y_buffer, stride_y, xpos, ypos, bs,
                         bs, width, height, strength);
            } else {  // Skip block, copy instead
              for (c = 0; c < bs; c++)
                *(uint64_t *)(dst->y_buffer + (ypos + c) * stride_y + xpos) =
                    *(uint64_t *)(rec->y_buffer + (ypos + c) * stride_y + xpos);
            }
          }
        }
      } else {  // Entire filter block is skip, copy
        for (m = 0; m < h; m++)
          memcpy(dst->y_buffer + ((k << fb_size_log2) + m) * stride_y +
                     (l << fb_size_log2),
                 rec->y_buffer + ((k << fb_size_log2) + m) * stride_y +
                     (l << fb_size_log2),
                 w);
      }
      block_index += !allskip;  // Count number of blocks filtered
    }
  }

  return block_index;
}
