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 159