1f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com/* 2f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com * Copyright 2013 The LibYuv Project Authors. All rights reserved. 3f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com * 4f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com * Use of this source code is governed by a BSD-style license 5f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com * that can be found in the LICENSE file in the root of the source 6f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com * tree. An additional intellectual property rights grant can be found 7f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com * in the file PATENTS. All contributing project authors may 8f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com * be found in the AUTHORS file in the root of the source tree. 9f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com */ 10f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 11f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com#include <stdlib.h> 12f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com#include <string.h> 13f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 14f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com#include "libyuv/basic_types.h" 15747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com#include "libyuv/cpu_id.h" 16a18ba50d2338a847d60ec69c00cab8d0f8002cc6fbarchard@google.com#include "libyuv/row.h" 175dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com#include "libyuv/scale.h" 185dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com#include "libyuv/scale_row.h" 19f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com#include "../unit_test/unit_test.h" 20f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 21f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.comnamespace libyuv { 22f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 23f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.comTEST_F(libyuvTest, TestFixedDiv) { 2448ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int num[1280]; 2548ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int div[1280]; 2648ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int result_opt[1280]; 2748ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int result_c[1280]; 2848ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com 2948ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com EXPECT_EQ(0x10000, libyuv::FixedDiv(1, 1)); 3048ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com EXPECT_EQ(0x7fff0000, libyuv::FixedDiv(0x7fff, 1)); 3148ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com // TODO(fbarchard): Avoid the following that throw exceptions. 325dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com // EXPECT_EQ(0x100000000, libyuv::FixedDiv(0x10000, 1)); 3348ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com // EXPECT_EQ(0x80000000, libyuv::FixedDiv(0x8000, 1)); 34f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 35c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x20000, libyuv::FixedDiv(640 * 2, 640)); 36c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x30000, libyuv::FixedDiv(640 * 3, 640)); 37c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x40000, libyuv::FixedDiv(640 * 4, 640)); 38c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x50000, libyuv::FixedDiv(640 * 5, 640)); 39c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x60000, libyuv::FixedDiv(640 * 6, 640)); 40c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x70000, libyuv::FixedDiv(640 * 7, 640)); 41c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x80000, libyuv::FixedDiv(640 * 8, 640)); 42c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0xa0000, libyuv::FixedDiv(640 * 10, 640)); 43c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x20000, libyuv::FixedDiv(960 * 2, 960)); 44c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x08000, libyuv::FixedDiv(640 / 2, 640)); 45c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x04000, libyuv::FixedDiv(640 / 4, 640)); 46c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x20000, libyuv::FixedDiv(1080 * 2, 1080)); 47c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x20000, libyuv::FixedDiv(200000, 100000)); 48c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x18000, libyuv::FixedDiv(150000, 100000)); 49c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x20000, libyuv::FixedDiv(40000, 20000)); 50c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x20000, libyuv::FixedDiv(-40000, -20000)); 51c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(-0x20000, libyuv::FixedDiv(40000, -20000)); 52c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(-0x20000, libyuv::FixedDiv(-40000, 20000)); 53e5d3e10ee88210f8290e6d62765e7f0f532b3cbcfbarchard@google.com EXPECT_EQ(0x10000, libyuv::FixedDiv(4095, 4095)); 54c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x10000, libyuv::FixedDiv(4096, 4096)); 55c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com EXPECT_EQ(0x10000, libyuv::FixedDiv(4097, 4097)); 56e5d3e10ee88210f8290e6d62765e7f0f532b3cbcfbarchard@google.com EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1)); 57c9f0d966edfb8247d0408daa63c599e20fc63ac7fbarchard@google.com 58595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com for (int i = 1; i < 4100; ++i) { 59595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com EXPECT_EQ(0x10000, libyuv::FixedDiv(i, i)); 60595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com EXPECT_EQ(0x20000, libyuv::FixedDiv(i * 2, i)); 61595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com EXPECT_EQ(0x30000, libyuv::FixedDiv(i * 3, i)); 62595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com EXPECT_EQ(0x40000, libyuv::FixedDiv(i * 4, i)); 63595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com EXPECT_EQ(0x08000, libyuv::FixedDiv(i, i * 2)); 64595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com EXPECT_NEAR(16384 * 65536 / i, libyuv::FixedDiv(16384, i), 1); 65595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com } 66595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com EXPECT_EQ(123 * 65536, libyuv::FixedDiv(123, 1)); 67595c2427e8543f5a4c1b73e6b2ec4973a5fa5970fbarchard@google.com 68f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com srandom(time(NULL)); 69f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num)); 70f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div)); 7148ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int j = 0; j < 1280; ++j) { 72f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com if (div[j] == 0) { 73f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com div[j] = 1280; 74f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 7548ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com num[j] &= 0xffff; // Clamp to avoid divide overflow. 76f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 7748ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 7848ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int j = 0; j < 1280; ++j) { 79f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com result_opt[j] = libyuv::FixedDiv(num[j], div[j]); 80f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 81f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 8248ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int j = 0; j < 1280; ++j) { 83f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com result_c[j] = libyuv::FixedDiv_C(num[j], div[j]); 84747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com EXPECT_NEAR(result_c[j], result_opt[j], 1); 85f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 86f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com} 87f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 88f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.comTEST_F(libyuvTest, TestFixedDiv_Opt) { 8948ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int num[1280]; 9048ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int div[1280]; 9148ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int result_opt[1280]; 9248ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com int result_c[1280]; 93f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 94f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com srandom(time(NULL)); 95f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num)); 96f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div)); 9748ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int j = 0; j < 1280; ++j) { 98f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com num[j] &= 4095; // Make numerator smaller. 99f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com div[j] &= 4095; // Make divisor smaller. 100f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com if (div[j] == 0) { 101f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com div[j] = 1280; 102f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 103f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 104747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com 105747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com int has_x86 = TestCpuFlag(kCpuHasX86); 10648ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 107747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com if (has_x86) { 10848ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int j = 0; j < 1280; ++j) { 109747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com result_opt[j] = libyuv::FixedDiv(num[j], div[j]); 110747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com } 111747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com } else { 11248ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int j = 0; j < 1280; ++j) { 113747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com result_opt[j] = libyuv::FixedDiv_C(num[j], div[j]); 114747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com } 115f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 116f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 11748ab3cf3f4c712daad439a271b4cc516d912b191fbarchard@google.com for (int j = 0; j < 1280; ++j) { 118f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com result_c[j] = libyuv::FixedDiv_C(num[j], div[j]); 119747ceb9fa5cea5c923d4b08acbb7f1cfa39f138efbarchard@google.com EXPECT_NEAR(result_c[j], result_opt[j], 1); 120f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com } 121f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com} 122f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com 1235dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.comTEST_F(libyuvTest, TestFixedDiv1_Opt) { 1245dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com int num[1280]; 1255dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com int div[1280]; 1265dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com int result_opt[1280]; 1275dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com int result_c[1280]; 1285dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com 1295dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com srandom(time(NULL)); 1305dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com MemRandomize(reinterpret_cast<uint8*>(&num[0]), sizeof(num)); 1315dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com MemRandomize(reinterpret_cast<uint8*>(&div[0]), sizeof(div)); 1325dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com for (int j = 0; j < 1280; ++j) { 1335dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com num[j] &= 4095; // Make numerator smaller. 1345dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com div[j] &= 4095; // Make divisor smaller. 1355dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com if (div[j] <= 1) { 1365dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com div[j] = 1280; 1375dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } 1385dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } 1395dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com 1405dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com int has_x86 = TestCpuFlag(kCpuHasX86); 1415dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1425dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com if (has_x86) { 1435dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com for (int j = 0; j < 1280; ++j) { 1445dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com result_opt[j] = libyuv::FixedDiv1(num[j], div[j]); 1455dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } 1465dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } else { 1475dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com for (int j = 0; j < 1280; ++j) { 1485dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com result_opt[j] = libyuv::FixedDiv1_C(num[j], div[j]); 1495dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } 1505dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } 1515dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } 1525dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com for (int j = 0; j < 1280; ++j) { 1535dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com result_c[j] = libyuv::FixedDiv1_C(num[j], div[j]); 1545dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com EXPECT_NEAR(result_c[j], result_opt[j], 1); 1555dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com } 1565dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com} 1575dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com 158f2f9dbb644626349de54d00caf68ef2290c91f91fbarchard@google.com} // namespace libyuv 159