/*
 * Copyright (c) 2017, 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.
 */

// Utility functions used by encoder binaries.

#include <assert.h>
#include <string.h>

#include "./encoder_util.h"
#include "aom/aom_integer.h"

#define mmin(a, b) ((a) < (b) ? (a) : (b))

static void find_mismatch_plane(const aom_image_t *const img1,
                                const aom_image_t *const img2, int plane,
                                int use_highbitdepth, int loc[4]) {
  const unsigned char *const p1 = img1->planes[plane];
  const int p1_stride = img1->stride[plane] >> use_highbitdepth;
  const unsigned char *const p2 = img2->planes[plane];
  const int p2_stride = img2->stride[plane] >> use_highbitdepth;
  const uint32_t bsize = 64;
  const int is_y_plane = (plane == AOM_PLANE_Y);
  const uint32_t bsizex = is_y_plane ? bsize : bsize >> img1->x_chroma_shift;
  const uint32_t bsizey = is_y_plane ? bsize : bsize >> img1->y_chroma_shift;
  const uint32_t c_w =
      is_y_plane ? img1->d_w
                 : (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
  const uint32_t c_h =
      is_y_plane ? img1->d_h
                 : (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
  assert(img1->d_w == img2->d_w && img1->d_h == img2->d_h);
  assert(img1->x_chroma_shift == img2->x_chroma_shift &&
         img1->y_chroma_shift == img2->y_chroma_shift);
  loc[0] = loc[1] = loc[2] = loc[3] = -1;
  int match = 1;
  uint32_t i, j;
  for (i = 0; match && i < c_h; i += bsizey) {
    for (j = 0; match && j < c_w; j += bsizex) {
      const int si =
          is_y_plane ? mmin(i + bsizey, c_h) - i : mmin(i + bsizey, c_h - i);
      const int sj =
          is_y_plane ? mmin(j + bsizex, c_w) - j : mmin(j + bsizex, c_w - j);
      int k, l;
      for (k = 0; match && k < si; ++k) {
        for (l = 0; match && l < sj; ++l) {
          const int row = i + k;
          const int col = j + l;
          const int offset1 = row * p1_stride + col;
          const int offset2 = row * p2_stride + col;
          const int val1 = use_highbitdepth
                               ? p1[2 * offset1] | (p1[2 * offset1 + 1] << 8)
                               : p1[offset1];
          const int val2 = use_highbitdepth
                               ? p2[2 * offset2] | (p2[2 * offset2 + 1] << 8)
                               : p2[offset2];
          if (val1 != val2) {
            loc[0] = row;
            loc[1] = col;
            loc[2] = val1;
            loc[3] = val2;
            match = 0;
            break;
          }
        }
      }
    }
  }
}

static void find_mismatch_helper(const aom_image_t *const img1,
                                 const aom_image_t *const img2,
                                 int use_highbitdepth, int yloc[4], int uloc[4],
                                 int vloc[4]) {
#if !CONFIG_HIGHBITDEPTH
  assert(!use_highbitdepth);
#endif  // !CONFIG_HIGHBITDEPTH
  find_mismatch_plane(img1, img2, AOM_PLANE_Y, use_highbitdepth, yloc);
  find_mismatch_plane(img1, img2, AOM_PLANE_U, use_highbitdepth, uloc);
  find_mismatch_plane(img1, img2, AOM_PLANE_V, use_highbitdepth, vloc);
}

#if CONFIG_HIGHBITDEPTH
void aom_find_mismatch_high(const aom_image_t *const img1,
                            const aom_image_t *const img2, int yloc[4],
                            int uloc[4], int vloc[4]) {
  find_mismatch_helper(img1, img2, 1, yloc, uloc, vloc);
}
#endif

void aom_find_mismatch(const aom_image_t *const img1,
                       const aom_image_t *const img2, int yloc[4], int uloc[4],
                       int vloc[4]) {
  find_mismatch_helper(img1, img2, 0, yloc, uloc, vloc);
}

int aom_compare_img(const aom_image_t *const img1,
                    const aom_image_t *const img2) {
  uint32_t l_w = img1->d_w;
  uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
  const uint32_t c_h =
      (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
  uint32_t i;
  int match = 1;

  match &= (img1->fmt == img2->fmt);
  match &= (img1->d_w == img2->d_w);
  match &= (img1->d_h == img2->d_h);
#if CONFIG_HIGHBITDEPTH
  if (img1->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
    l_w *= 2;
    c_w *= 2;
  }
#endif

  for (i = 0; i < img1->d_h; ++i)
    match &= (memcmp(img1->planes[AOM_PLANE_Y] + i * img1->stride[AOM_PLANE_Y],
                     img2->planes[AOM_PLANE_Y] + i * img2->stride[AOM_PLANE_Y],
                     l_w) == 0);

  for (i = 0; i < c_h; ++i)
    match &= (memcmp(img1->planes[AOM_PLANE_U] + i * img1->stride[AOM_PLANE_U],
                     img2->planes[AOM_PLANE_U] + i * img2->stride[AOM_PLANE_U],
                     c_w) == 0);

  for (i = 0; i < c_h; ++i)
    match &= (memcmp(img1->planes[AOM_PLANE_V] + i * img1->stride[AOM_PLANE_V],
                     img2->planes[AOM_PLANE_V] + i * img2->stride[AOM_PLANE_V],
                     c_w) == 0);

  return match;
}
