/*
 *  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 <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h"
extern "C" {
#include "vp8/encoder/onyx_int.h"
}

using libvpx_test::ACMRandom;

namespace {

TEST(Vp8RoiMapTest, ParameterCheck) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  int delta_q[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
  int delta_lf[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
  unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 };

  const int internalq_trans[] = {
    0,   1,  2,  3,  4,  5,  7,  8,
    9,  10, 12, 13, 15, 17, 18, 19,
    20,  21, 23, 24, 25, 26, 27, 28,
    29,  30, 31, 33, 35, 37, 39, 41,
    43,  45, 47, 49, 51, 53, 55, 57,
    59,  61, 64, 67, 70, 73, 76, 79,
    82,  85, 88, 91, 94, 97, 100, 103,
    106, 109, 112, 115, 118, 121, 124, 127,
  };

  // Initialize elements of cpi with valid defaults.
  VP8_COMP cpi;
  cpi.mb.e_mbd.mb_segement_abs_delta = SEGMENT_DELTADATA;
  cpi.cyclic_refresh_mode_enabled = 0;
  cpi.mb.e_mbd.segmentation_enabled = 0;
  cpi.mb.e_mbd.update_mb_segmentation_map = 0;
  cpi.mb.e_mbd.update_mb_segmentation_data = 0;
  cpi.common.mb_rows = 240 >> 4;
  cpi.common.mb_cols = 320 >> 4;
  const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols);
  vpx_memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data));

  // Segment map
  cpi.segmentation_map = reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));

  // Allocate memory for the source memory map.
  unsigned char *roi_map =
    reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
  vpx_memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
  vpx_memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
  vpx_memset(&roi_map[mbs -(mbs >> 2)], 3, (mbs >> 2));

  // Do a test call with valid parameters.
  int roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
                                  cpi.common.mb_cols, delta_q, delta_lf,
                                  threshold);
  EXPECT_EQ(0, roi_retval)
        << "vp8_set_roimap roi failed with default test parameters";

  // Check that the values in the cpi structure get set as expected.
  if (roi_retval == 0) {
    // Check that the segment map got set.
    const int mapcompare = memcmp(roi_map, cpi.segmentation_map, mbs);
    EXPECT_EQ(0, mapcompare) << "segment map error";

    // Check the q deltas (note the need to translate into
    // the interanl range of 0-127.
    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
      const int transq = internalq_trans[abs(delta_q[i])];
      if (abs(cpi.segment_feature_data[MB_LVL_ALT_Q][i]) != transq) {
          EXPECT_EQ(transq, cpi.segment_feature_data[MB_LVL_ALT_Q][i])
                    << "segment delta_q  error";
          break;
      }
    }

    // Check the loop filter deltas
    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
      if (cpi.segment_feature_data[MB_LVL_ALT_LF][i] != delta_lf[i]) {
        EXPECT_EQ(delta_lf[i], cpi.segment_feature_data[MB_LVL_ALT_LF][i])
                  << "segment delta_lf error";
        break;
      }
    }

    // Check the breakout thresholds
    for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
      unsigned int breakout =
        static_cast<unsigned int>(cpi.segment_encode_breakout[i]);

      if (threshold[i] != breakout) {
        EXPECT_EQ(threshold[i], breakout)
                  << "breakout threshold error";
        break;
      }
    }

    // Segmentation, and segmentation update flages should be set.
    EXPECT_EQ(1, cpi.mb.e_mbd.segmentation_enabled)
              << "segmentation_enabled error";
    EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_map)
              << "update_mb_segmentation_map error";
    EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data)
              << "update_mb_segmentation_data error";


    // Try a range of delta q and lf parameters (some legal, some not)
    for (int i = 0; i < 1000; ++i) {
      int rand_deltas[4];
      int deltas_valid;
      rand_deltas[0] = rnd(160) - 80;
      rand_deltas[1] = rnd(160) - 80;
      rand_deltas[2] = rnd(160) - 80;
      rand_deltas[3] = rnd(160) - 80;

      deltas_valid = ((abs(rand_deltas[0]) <= 63) &&
                      (abs(rand_deltas[1]) <= 63) &&
                      (abs(rand_deltas[2]) <= 63) &&
                      (abs(rand_deltas[3]) <= 63)) ? 0 : -1;

      // Test with random delta q values.
      roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
                                  cpi.common.mb_cols, rand_deltas,
                                  delta_lf, threshold);
      EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error";

      // One delta_q error shown at a time
      if (deltas_valid != roi_retval)
        break;

      // Test with random loop filter values.
      roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
                                  cpi.common.mb_cols, delta_q,
                                  rand_deltas, threshold);
      EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error";

      // One delta loop filter error shown at a time
      if (deltas_valid != roi_retval)
        break;
    }

    // Test that we report and error if cyclic refresh is enabled.
    cpi.cyclic_refresh_mode_enabled = 1;
    roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
                                cpi.common.mb_cols, delta_q,
                                delta_lf, threshold);
    EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error";
    cpi.cyclic_refresh_mode_enabled = 0;

    // Test invalid number of rows or colums.
    roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
                                cpi.common.mb_cols, delta_q,
                                delta_lf, threshold);
    EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error";

    roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
                                cpi.common.mb_cols - 1, delta_q,
                                delta_lf, threshold);
    EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error";
  }

  // Free allocated memory
  if (cpi.segmentation_map)
    vpx_free(cpi.segmentation_map);
  if (roi_map)
    vpx_free(roi_map);
};

}  // namespace
