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