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