math_test.cc 5.02 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/*
 *  Copyright 2013 The LibYuv 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 <stdlib.h>
#include <string.h>
13
#include <time.h>
14 15

#include "libyuv/basic_types.h"
16
#include "libyuv/cpu_id.h"
17
#include "libyuv/row.h"
18 19
#include "libyuv/scale.h"
#include "libyuv/scale_row.h"
20 21 22 23
#include "../unit_test/unit_test.h"

namespace libyuv {

24
TEST_F(LibYUVBaseTest, TestFixedDiv) {
25 26 27 28 29 30 31 32
  int num[1280];
  int div[1280];
  int result_opt[1280];
  int result_c[1280];

  EXPECT_EQ(0x10000, libyuv::FixedDiv(1, 1));
  EXPECT_EQ(0x7fff0000, libyuv::FixedDiv(0x7fff, 1));
  // TODO(fbarchard): Avoid the following that throw exceptions.
33
  // EXPECT_EQ(0x100000000, libyuv::FixedDiv(0x10000, 1));
34
  // EXPECT_EQ(0x80000000, libyuv::FixedDiv(0x8000, 1));
35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
  EXPECT_EQ(0x20000, libyuv::FixedDiv(640 * 2, 640));
  EXPECT_EQ(0x30000, libyuv::FixedDiv(640 * 3, 640));
  EXPECT_EQ(0x40000, libyuv::FixedDiv(640 * 4, 640));
  EXPECT_EQ(0x50000, libyuv::FixedDiv(640 * 5, 640));
  EXPECT_EQ(0x60000, libyuv::FixedDiv(640 * 6, 640));
  EXPECT_EQ(0x70000, libyuv::FixedDiv(640 * 7, 640));
  EXPECT_EQ(0x80000, libyuv::FixedDiv(640 * 8, 640));
  EXPECT_EQ(0xa0000, libyuv::FixedDiv(640 * 10, 640));
  EXPECT_EQ(0x20000, libyuv::FixedDiv(960 * 2, 960));
  EXPECT_EQ(0x08000, libyuv::FixedDiv(640 / 2, 640));
  EXPECT_EQ(0x04000, libyuv::FixedDiv(640 / 4, 640));
  EXPECT_EQ(0x20000, libyuv::FixedDiv(1080 * 2, 1080));
  EXPECT_EQ(0x20000, libyuv::FixedDiv(200000, 100000));
  EXPECT_EQ(0x18000, libyuv::FixedDiv(150000, 100000));
  EXPECT_EQ(0x20000, libyuv::FixedDiv(40000, 20000));
  EXPECT_EQ(0x20000, libyuv::FixedDiv(-40000, -20000));
  EXPECT_EQ(-0x20000, libyuv::FixedDiv(40000, -20000));
  EXPECT_EQ(-0x20000, libyuv::FixedDiv(-40000, 20000));
54
  EXPECT_EQ(0x10000, libyuv::FixedDiv(4095, 4095));
55 56
  EXPECT_EQ(0x10000, libyuv::FixedDiv(4096, 4096));
  EXPECT_EQ(0x10000, libyuv::FixedDiv(4097, 4097));
57
  EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1));
58

59 60 61 62 63 64 65 66 67 68
  for (int i = 1; i < 4100; ++i) {
    EXPECT_EQ(0x10000, libyuv::FixedDiv(i, i));
    EXPECT_EQ(0x20000, libyuv::FixedDiv(i * 2, i));
    EXPECT_EQ(0x30000, libyuv::FixedDiv(i * 3, i));
    EXPECT_EQ(0x40000, libyuv::FixedDiv(i * 4, i));
    EXPECT_EQ(0x08000, libyuv::FixedDiv(i, i * 2));
    EXPECT_NEAR(16384 * 65536 / i, libyuv::FixedDiv(16384, i), 1);
  }
  EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1));

69 70
  MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num));
  MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div));
71
  for (int j = 0; j < 1280; ++j) {
72 73 74
    if (div[j] == 0) {
      div[j] = 1280;
    }
75
    num[j] &= 0xffff;  // Clamp to avoid divide overflow.
76
  }
77 78
  for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    for (int j = 0; j < 1280; ++j) {
79 80 81
      result_opt[j] = libyuv::FixedDiv(num[j], div[j]);
    }
  }
82
  for (int j = 0; j < 1280; ++j) {
83
    result_c[j] = libyuv::FixedDiv_C(num[j], div[j]);
84
    EXPECT_NEAR(result_c[j], result_opt[j], 1);
85 86 87
  }
}

88
TEST_F(LibYUVBaseTest, TestFixedDiv_Opt) {
89 90 91 92
  int num[1280];
  int div[1280];
  int result_opt[1280];
  int result_c[1280];
93 94 95

  MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num));
  MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div));
96
  for (int j = 0; j < 1280; ++j) {
97 98 99 100 101 102
    num[j] &= 4095;  // Make numerator smaller.
    div[j] &= 4095;  // Make divisor smaller.
    if (div[j] == 0) {
      div[j] = 1280;
    }
  }
103 104

  int has_x86 = TestCpuFlag(kCpuHasX86);
105
  for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
106
    if (has_x86) {
107
      for (int j = 0; j < 1280; ++j) {
108 109 110
        result_opt[j] = libyuv::FixedDiv(num[j], div[j]);
      }
    } else {
111
      for (int j = 0; j < 1280; ++j) {
112 113
        result_opt[j] = libyuv::FixedDiv_C(num[j], div[j]);
      }
114 115
    }
  }
116
  for (int j = 0; j < 1280; ++j) {
117
    result_c[j] = libyuv::FixedDiv_C(num[j], div[j]);
118
    EXPECT_NEAR(result_c[j], result_opt[j], 1);
119 120 121
  }
}

122
TEST_F(LibYUVBaseTest, TestFixedDiv1_Opt) {
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
  int num[1280];
  int div[1280];
  int result_opt[1280];
  int result_c[1280];

  MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num));
  MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div));
  for (int j = 0; j < 1280; ++j) {
    num[j] &= 4095;  // Make numerator smaller.
    div[j] &= 4095;  // Make divisor smaller.
    if (div[j] <= 1) {
      div[j] = 1280;
    }
  }

  int has_x86 = TestCpuFlag(kCpuHasX86);
  for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    if (has_x86) {
      for (int j = 0; j < 1280; ++j) {
        result_opt[j] = libyuv::FixedDiv1(num[j], div[j]);
      }
    } else {
      for (int j = 0; j < 1280; ++j) {
        result_opt[j] = libyuv::FixedDiv1_C(num[j], div[j]);
      }
    }
  }
  for (int j = 0; j < 1280; ++j) {
    result_c[j] = libyuv::FixedDiv1_C(num[j], div[j]);
    EXPECT_NEAR(result_c[j], result_opt[j], 1);
  }
}

156
}  // namespace libyuv