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