/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE 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.
 */

#include <limits.h>
#include <stdio.h>
#include <string.h>

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./vpx_config.h"
#if CONFIG_VP9_ENCODER
#include "./vp10_rtcd.h"
#endif

#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"

#include "vpx_mem/vpx_mem.h"


extern "C"
double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
                          const unsigned char *img2, int img2_pitch,
                          int width, int height);

using libvpx_test::ACMRandom;

namespace {
class BlockinessTestBase : public ::testing::Test {
 public:
  BlockinessTestBase(int width, int height) : width_(width), height_(height) {}

  static void SetUpTestCase() {
    source_data_ = reinterpret_cast<uint8_t*>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
    reference_data_ = reinterpret_cast<uint8_t*>(
        vpx_memalign(kDataAlignment, kDataBufferSize));
  }

  static void TearDownTestCase() {
    vpx_free(source_data_);
    source_data_ = NULL;
    vpx_free(reference_data_);
    reference_data_ = NULL;
  }

  virtual void TearDown() {
    libvpx_test::ClearSystemState();
  }

 protected:
  // Handle frames up to 640x480
  static const int kDataAlignment = 16;
  static const int kDataBufferSize = 640*480;

  virtual void SetUp() {
    source_stride_ = (width_ + 31) & ~31;
    reference_stride_ = width_ * 2;
    rnd_.Reset(ACMRandom::DeterministicSeed());
  }

  void FillConstant(uint8_t *data, int stride, uint8_t fill_constant,
                    int width, int height) {
    for (int h = 0; h < height; ++h) {
      for (int w = 0; w < width; ++w) {
        data[h * stride + w] = fill_constant;
      }
    }
  }

  void FillConstant(uint8_t *data, int stride, uint8_t fill_constant) {
    FillConstant(data, stride, fill_constant, width_, height_);
  }

  void FillRandom(uint8_t *data, int stride, int width, int height) {
    for (int h = 0; h < height; ++h) {
      for (int w = 0; w < width; ++w) {
        data[h * stride + w] = rnd_.Rand8();
      }
    }
  }

  void FillRandom(uint8_t *data, int stride) {
    FillRandom(data, stride, width_, height_);
  }

  void FillRandomBlocky(uint8_t *data, int stride) {
    for (int h = 0; h < height_; h += 4) {
      for (int w = 0; w < width_; w += 4) {
        FillRandom(data + h * stride + w, stride, 4, 4);
      }
    }
  }

  void FillCheckerboard(uint8_t *data, int stride) {
    for (int h = 0; h < height_; h += 4) {
      for (int w = 0; w < width_; w += 4) {
        if (((h/4) ^ (w/4)) & 1)
          FillConstant(data + h * stride + w, stride, 255, 4, 4);
        else
          FillConstant(data + h * stride + w, stride, 0, 4, 4);
      }
    }
  }

  void Blur(uint8_t *data, int stride, int taps) {
    int sum = 0;
    int half_taps = taps / 2;
    for (int h = 0; h < height_; ++h) {
      for (int w = 0; w < taps; ++w) {
        sum += data[w + h * stride];
      }
      for (int w = taps; w < width_; ++w) {
        sum += data[w + h * stride] - data[w - taps + h * stride];
        data[w - half_taps + h * stride] = (sum + half_taps) / taps;
      }
    }
    for (int w = 0; w < width_; ++w) {
      for (int h = 0; h < taps; ++h) {
        sum += data[h + w * stride];
      }
      for (int h = taps; h < height_; ++h) {
        sum += data[w + h * stride] - data[(h - taps) * stride + w];
        data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
      }
    }
  }
  int width_, height_;
  static uint8_t* source_data_;
  int source_stride_;
  static uint8_t* reference_data_;
  int reference_stride_;

  ACMRandom rnd_;
};

#if CONFIG_VP9_ENCODER
typedef std::tr1::tuple<int, int> BlockinessParam;
class BlockinessVP9Test
    : public BlockinessTestBase,
      public ::testing::WithParamInterface<BlockinessParam> {
 public:
  BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {}

 protected:
  int CheckBlockiness() {
    return vp9_get_blockiness(source_data_, source_stride_,
                              reference_data_, reference_stride_,
                              width_, height_);
  }
};
#endif  // CONFIG_VP9_ENCODER

uint8_t* BlockinessTestBase::source_data_ = NULL;
uint8_t* BlockinessTestBase::reference_data_ = NULL;

#if CONFIG_VP9_ENCODER
TEST_P(BlockinessVP9Test, SourceBlockierThanReference) {
  // Source is blockier than reference.
  FillRandomBlocky(source_data_, source_stride_);
  FillConstant(reference_data_, reference_stride_, 128);
  int super_blocky = CheckBlockiness();

  EXPECT_EQ(0, super_blocky) << "Blocky source should produce 0 blockiness.";
}

TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) {
  // Source is blockier than reference.
  FillConstant(source_data_, source_stride_, 128);
  FillRandomBlocky(reference_data_, reference_stride_);
  int super_blocky = CheckBlockiness();

  EXPECT_GT(super_blocky, 0.0)
      << "Blocky reference should score high for blockiness.";
}

TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) {
  // Source is blockier than reference.
  FillConstant(source_data_, source_stride_, 128);
  FillRandomBlocky(reference_data_, reference_stride_);
  int super_blocky = CheckBlockiness();

  Blur(reference_data_, reference_stride_, 4);
  int less_blocky = CheckBlockiness();

  EXPECT_GT(super_blocky, less_blocky)
      << "A straight blur should decrease blockiness.";
}

TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
  // Source is blockier than reference.
  FillConstant(source_data_, source_stride_, 128);
  FillCheckerboard(reference_data_, reference_stride_);

  int super_blocky = CheckBlockiness();

  Blur(reference_data_, reference_stride_, 4);
  int less_blocky = CheckBlockiness();

  EXPECT_GT(super_blocky, less_blocky)
      << "A straight blur should decrease blockiness.";
}
#endif  // CONFIG_VP9_ENCODER


using std::tr1::make_tuple;

//------------------------------------------------------------------------------
// C functions

#if CONFIG_VP9_ENCODER
const BlockinessParam c_vp9_tests[] = {
  make_tuple(320, 240),
  make_tuple(318, 242),
  make_tuple(318, 238),
};
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
#endif

}  // namespace
