/*
 *  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 "vp8/encoder/onyx_int.h"
#include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.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);
  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));
  memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
  memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
  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 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
