math_test.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright 2013 The LibYuv Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include "../unit_test/unit_test.h"
  14. #include "libyuv/basic_types.h"
  15. #include "libyuv/cpu_id.h"
  16. #include "libyuv/scale.h"
  17. #ifdef ENABLE_ROW_TESTS
  18. #include "libyuv/scale_row.h"
  19. #endif
  20. namespace libyuv {
  21. #ifdef ENABLE_ROW_TESTS
  22. TEST_F(LibYUVBaseTest, TestFixedDiv) {
  23. int num[1280];
  24. int div[1280];
  25. int result_opt[1280];
  26. int result_c[1280];
  27. EXPECT_EQ(0x10000, libyuv::FixedDiv(1, 1));
  28. EXPECT_EQ(0x7fff0000, libyuv::FixedDiv(0x7fff, 1));
  29. // TODO(fbarchard): Avoid the following that throw exceptions.
  30. // EXPECT_EQ(0x100000000, libyuv::FixedDiv(0x10000, 1));
  31. // EXPECT_EQ(0x80000000, libyuv::FixedDiv(0x8000, 1));
  32. EXPECT_EQ(0x20000, libyuv::FixedDiv(640 * 2, 640));
  33. EXPECT_EQ(0x30000, libyuv::FixedDiv(640 * 3, 640));
  34. EXPECT_EQ(0x40000, libyuv::FixedDiv(640 * 4, 640));
  35. EXPECT_EQ(0x50000, libyuv::FixedDiv(640 * 5, 640));
  36. EXPECT_EQ(0x60000, libyuv::FixedDiv(640 * 6, 640));
  37. EXPECT_EQ(0x70000, libyuv::FixedDiv(640 * 7, 640));
  38. EXPECT_EQ(0x80000, libyuv::FixedDiv(640 * 8, 640));
  39. EXPECT_EQ(0xa0000, libyuv::FixedDiv(640 * 10, 640));
  40. EXPECT_EQ(0x20000, libyuv::FixedDiv(960 * 2, 960));
  41. EXPECT_EQ(0x08000, libyuv::FixedDiv(640 / 2, 640));
  42. EXPECT_EQ(0x04000, libyuv::FixedDiv(640 / 4, 640));
  43. EXPECT_EQ(0x20000, libyuv::FixedDiv(1080 * 2, 1080));
  44. EXPECT_EQ(0x20000, libyuv::FixedDiv(200000, 100000));
  45. EXPECT_EQ(0x18000, libyuv::FixedDiv(150000, 100000));
  46. EXPECT_EQ(0x20000, libyuv::FixedDiv(40000, 20000));
  47. EXPECT_EQ(0x20000, libyuv::FixedDiv(-40000, -20000));
  48. EXPECT_EQ(-0x20000, libyuv::FixedDiv(40000, -20000));
  49. EXPECT_EQ(-0x20000, libyuv::FixedDiv(-40000, 20000));
  50. EXPECT_EQ(0x10000, libyuv::FixedDiv(4095, 4095));
  51. EXPECT_EQ(0x10000, libyuv::FixedDiv(4096, 4096));
  52. EXPECT_EQ(0x10000, libyuv::FixedDiv(4097, 4097));
  53. EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1));
  54. for (int i = 1; i < 4100; ++i) {
  55. EXPECT_EQ(0x10000, libyuv::FixedDiv(i, i));
  56. EXPECT_EQ(0x20000, libyuv::FixedDiv(i * 2, i));
  57. EXPECT_EQ(0x30000, libyuv::FixedDiv(i * 3, i));
  58. EXPECT_EQ(0x40000, libyuv::FixedDiv(i * 4, i));
  59. EXPECT_EQ(0x08000, libyuv::FixedDiv(i, i * 2));
  60. EXPECT_NEAR(16384 * 65536 / i, libyuv::FixedDiv(16384, i), 1);
  61. }
  62. EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1));
  63. MemRandomize(reinterpret_cast<uint8_t*>(&num[0]), sizeof(num));
  64. MemRandomize(reinterpret_cast<uint8_t*>(&div[0]), sizeof(div));
  65. for (int j = 0; j < 1280; ++j) {
  66. if (div[j] == 0) {
  67. div[j] = 1280;
  68. }
  69. num[j] &= 0xffff; // Clamp to avoid divide overflow.
  70. }
  71. for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
  72. for (int j = 0; j < 1280; ++j) {
  73. result_opt[j] = libyuv::FixedDiv(num[j], div[j]);
  74. }
  75. }
  76. for (int j = 0; j < 1280; ++j) {
  77. result_c[j] = libyuv::FixedDiv_C(num[j], div[j]);
  78. EXPECT_NEAR(result_c[j], result_opt[j], 1);
  79. }
  80. }
  81. TEST_F(LibYUVBaseTest, TestFixedDiv_Opt) {
  82. int num[1280];
  83. int div[1280];
  84. int result_opt[1280];
  85. int result_c[1280];
  86. MemRandomize(reinterpret_cast<uint8_t*>(&num[0]), sizeof(num));
  87. MemRandomize(reinterpret_cast<uint8_t*>(&div[0]), sizeof(div));
  88. for (int j = 0; j < 1280; ++j) {
  89. num[j] &= 4095; // Make numerator smaller.
  90. div[j] &= 4095; // Make divisor smaller.
  91. if (div[j] == 0) {
  92. div[j] = 1280;
  93. }
  94. }
  95. int has_x86 = TestCpuFlag(kCpuHasX86);
  96. for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
  97. if (has_x86) {
  98. for (int j = 0; j < 1280; ++j) {
  99. result_opt[j] = libyuv::FixedDiv(num[j], div[j]);
  100. }
  101. } else {
  102. for (int j = 0; j < 1280; ++j) {
  103. result_opt[j] = libyuv::FixedDiv_C(num[j], div[j]);
  104. }
  105. }
  106. }
  107. for (int j = 0; j < 1280; ++j) {
  108. result_c[j] = libyuv::FixedDiv_C(num[j], div[j]);
  109. EXPECT_NEAR(result_c[j], result_opt[j], 1);
  110. }
  111. }
  112. TEST_F(LibYUVBaseTest, TestFixedDiv1_Opt) {
  113. int num[1280];
  114. int div[1280];
  115. int result_opt[1280];
  116. int result_c[1280];
  117. MemRandomize(reinterpret_cast<uint8_t*>(&num[0]), sizeof(num));
  118. MemRandomize(reinterpret_cast<uint8_t*>(&div[0]), sizeof(div));
  119. for (int j = 0; j < 1280; ++j) {
  120. num[j] &= 4095; // Make numerator smaller.
  121. div[j] &= 4095; // Make divisor smaller.
  122. if (div[j] <= 1) {
  123. div[j] = 1280;
  124. }
  125. }
  126. int has_x86 = TestCpuFlag(kCpuHasX86);
  127. for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
  128. if (has_x86) {
  129. for (int j = 0; j < 1280; ++j) {
  130. result_opt[j] = libyuv::FixedDiv1(num[j], div[j]);
  131. }
  132. } else {
  133. for (int j = 0; j < 1280; ++j) {
  134. result_opt[j] = libyuv::FixedDiv1_C(num[j], div[j]);
  135. }
  136. }
  137. }
  138. for (int j = 0; j < 1280; ++j) {
  139. result_c[j] = libyuv::FixedDiv1_C(num[j], div[j]);
  140. EXPECT_NEAR(result_c[j], result_opt[j], 1);
  141. }
  142. }
  143. #endif // ENABLE_ROW_TESTS
  144. } // namespace libyuv