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