1 /* 2 * Copyright 2011 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 <time.h> 13 14 #include "libyuv/compare.h" 15 #include "libyuv/convert.h" 16 #include "libyuv/convert_argb.h" 17 #include "libyuv/convert_from.h" 18 #include "libyuv/convert_from_argb.h" 19 #include "libyuv/cpu_id.h" 20 #include "libyuv/format_conversion.h" 21 #include "libyuv/planar_functions.h" 22 #include "libyuv/rotate.h" 23 #include "libyuv/row.h" // For Sobel 24 #include "../unit_test/unit_test.h" 25 26 #if defined(_MSC_VER) 27 #define SIMD_ALIGNED(var) __declspec(align(16)) var 28 #else // __GNUC__ 29 #define SIMD_ALIGNED(var) var __attribute__((aligned(16))) 30 #endif 31 32 namespace libyuv { 33 34 TEST_F(libyuvTest, TestAttenuate) { 35 const int kSize = 1280 * 4; 36 align_buffer_64(orig_pixels, kSize); 37 align_buffer_64(atten_pixels, kSize); 38 align_buffer_64(unatten_pixels, kSize); 39 align_buffer_64(atten2_pixels, kSize); 40 41 // Test unattenuation clamps 42 orig_pixels[0 * 4 + 0] = 200u; 43 orig_pixels[0 * 4 + 1] = 129u; 44 orig_pixels[0 * 4 + 2] = 127u; 45 orig_pixels[0 * 4 + 3] = 128u; 46 // Test unattenuation transparent and opaque are unaffected 47 orig_pixels[1 * 4 + 0] = 16u; 48 orig_pixels[1 * 4 + 1] = 64u; 49 orig_pixels[1 * 4 + 2] = 192u; 50 orig_pixels[1 * 4 + 3] = 0u; 51 orig_pixels[2 * 4 + 0] = 16u; 52 orig_pixels[2 * 4 + 1] = 64u; 53 orig_pixels[2 * 4 + 2] = 192u; 54 orig_pixels[2 * 4 + 3] = 255u; 55 orig_pixels[3 * 4 + 0] = 16u; 56 orig_pixels[3 * 4 + 1] = 64u; 57 orig_pixels[3 * 4 + 2] = 192u; 58 orig_pixels[3 * 4 + 3] = 128u; 59 ARGBUnattenuate(orig_pixels, 0, unatten_pixels, 0, 4, 1); 60 EXPECT_EQ(255u, unatten_pixels[0 * 4 + 0]); 61 EXPECT_EQ(255u, unatten_pixels[0 * 4 + 1]); 62 EXPECT_EQ(254u, unatten_pixels[0 * 4 + 2]); 63 EXPECT_EQ(128u, unatten_pixels[0 * 4 + 3]); 64 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 0]); 65 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 1]); 66 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 2]); 67 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 3]); 68 EXPECT_EQ(16u, unatten_pixels[2 * 4 + 0]); 69 EXPECT_EQ(64u, unatten_pixels[2 * 4 + 1]); 70 EXPECT_EQ(192u, unatten_pixels[2 * 4 + 2]); 71 EXPECT_EQ(255u, unatten_pixels[2 * 4 + 3]); 72 EXPECT_EQ(32u, unatten_pixels[3 * 4 + 0]); 73 EXPECT_EQ(128u, unatten_pixels[3 * 4 + 1]); 74 EXPECT_EQ(255u, unatten_pixels[3 * 4 + 2]); 75 EXPECT_EQ(128u, unatten_pixels[3 * 4 + 3]); 76 77 for (int i = 0; i < 1280; ++i) { 78 orig_pixels[i * 4 + 0] = i; 79 orig_pixels[i * 4 + 1] = i / 2; 80 orig_pixels[i * 4 + 2] = i / 3; 81 orig_pixels[i * 4 + 3] = i; 82 } 83 ARGBAttenuate(orig_pixels, 0, atten_pixels, 0, 1280, 1); 84 ARGBUnattenuate(atten_pixels, 0, unatten_pixels, 0, 1280, 1); 85 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 86 ARGBAttenuate(unatten_pixels, 0, atten2_pixels, 0, 1280, 1); 87 } 88 for (int i = 0; i < 1280; ++i) { 89 EXPECT_NEAR(atten_pixels[i * 4 + 0], atten2_pixels[i * 4 + 0], 2); 90 EXPECT_NEAR(atten_pixels[i * 4 + 1], atten2_pixels[i * 4 + 1], 2); 91 EXPECT_NEAR(atten_pixels[i * 4 + 2], atten2_pixels[i * 4 + 2], 2); 92 EXPECT_NEAR(atten_pixels[i * 4 + 3], atten2_pixels[i * 4 + 3], 2); 93 } 94 // Make sure transparent, 50% and opaque are fully accurate. 95 EXPECT_EQ(0, atten_pixels[0 * 4 + 0]); 96 EXPECT_EQ(0, atten_pixels[0 * 4 + 1]); 97 EXPECT_EQ(0, atten_pixels[0 * 4 + 2]); 98 EXPECT_EQ(0, atten_pixels[0 * 4 + 3]); 99 EXPECT_EQ(64, atten_pixels[128 * 4 + 0]); 100 EXPECT_EQ(32, atten_pixels[128 * 4 + 1]); 101 EXPECT_EQ(21, atten_pixels[128 * 4 + 2]); 102 EXPECT_EQ(128, atten_pixels[128 * 4 + 3]); 103 EXPECT_NEAR(255, atten_pixels[255 * 4 + 0], 1); 104 EXPECT_NEAR(127, atten_pixels[255 * 4 + 1], 1); 105 EXPECT_NEAR(85, atten_pixels[255 * 4 + 2], 1); 106 EXPECT_EQ(255, atten_pixels[255 * 4 + 3]); 107 108 free_aligned_buffer_64(atten2_pixels); 109 free_aligned_buffer_64(unatten_pixels); 110 free_aligned_buffer_64(atten_pixels); 111 free_aligned_buffer_64(orig_pixels); 112 } 113 114 static int TestAttenuateI(int width, int height, int benchmark_iterations, 115 int invert, int off) { 116 if (width < 1) { 117 width = 1; 118 } 119 const int kBpp = 4; 120 const int kStride = (width * kBpp + 15) & ~15; 121 align_buffer_64(src_argb, kStride * height + off); 122 align_buffer_64(dst_argb_c, kStride * height); 123 align_buffer_64(dst_argb_opt, kStride * height); 124 srandom(time(NULL)); 125 for (int i = 0; i < kStride * height; ++i) { 126 src_argb[i + off] = (random() & 0xff); 127 } 128 memset(dst_argb_c, 0, kStride * height); 129 memset(dst_argb_opt, 0, kStride * height); 130 131 MaskCpuFlags(0); 132 ARGBAttenuate(src_argb + off, kStride, 133 dst_argb_c, kStride, 134 width, invert * height); 135 MaskCpuFlags(-1); 136 for (int i = 0; i < benchmark_iterations; ++i) { 137 ARGBAttenuate(src_argb + off, kStride, 138 dst_argb_opt, kStride, 139 width, invert * height); 140 } 141 int max_diff = 0; 142 for (int i = 0; i < kStride * height; ++i) { 143 int abs_diff = 144 abs(static_cast<int>(dst_argb_c[i]) - 145 static_cast<int>(dst_argb_opt[i])); 146 if (abs_diff > max_diff) { 147 max_diff = abs_diff; 148 } 149 } 150 free_aligned_buffer_64(src_argb); 151 free_aligned_buffer_64(dst_argb_c); 152 free_aligned_buffer_64(dst_argb_opt); 153 return max_diff; 154 } 155 156 TEST_F(libyuvTest, ARGBAttenuate_Any) { 157 int max_diff = TestAttenuateI(benchmark_width_ - 1, benchmark_height_, 158 benchmark_iterations_, +1, 0); 159 EXPECT_LE(max_diff, 2); 160 } 161 162 TEST_F(libyuvTest, ARGBAttenuate_Unaligned) { 163 int max_diff = TestAttenuateI(benchmark_width_, benchmark_height_, 164 benchmark_iterations_, +1, 1); 165 EXPECT_LE(max_diff, 2); 166 } 167 168 TEST_F(libyuvTest, ARGBAttenuate_Invert) { 169 int max_diff = TestAttenuateI(benchmark_width_, benchmark_height_, 170 benchmark_iterations_, -1, 0); 171 EXPECT_LE(max_diff, 2); 172 } 173 174 TEST_F(libyuvTest, ARGBAttenuate_Opt) { 175 int max_diff = TestAttenuateI(benchmark_width_, benchmark_height_, 176 benchmark_iterations_, +1, 0); 177 EXPECT_LE(max_diff, 2); 178 } 179 180 static int TestUnattenuateI(int width, int height, int benchmark_iterations, 181 int invert, int off) { 182 if (width < 1) { 183 width = 1; 184 } 185 const int kBpp = 4; 186 const int kStride = (width * kBpp + 15) & ~15; 187 align_buffer_64(src_argb, kStride * height + off); 188 align_buffer_64(dst_argb_c, kStride * height); 189 align_buffer_64(dst_argb_opt, kStride * height); 190 srandom(time(NULL)); 191 for (int i = 0; i < kStride * height; ++i) { 192 src_argb[i + off] = (random() & 0xff); 193 } 194 ARGBAttenuate(src_argb + off, kStride, 195 src_argb + off, kStride, 196 width, height); 197 memset(dst_argb_c, 0, kStride * height); 198 memset(dst_argb_opt, 0, kStride * height); 199 200 MaskCpuFlags(0); 201 ARGBUnattenuate(src_argb + off, kStride, 202 dst_argb_c, kStride, 203 width, invert * height); 204 MaskCpuFlags(-1); 205 for (int i = 0; i < benchmark_iterations; ++i) { 206 ARGBUnattenuate(src_argb + off, kStride, 207 dst_argb_opt, kStride, 208 width, invert * height); 209 } 210 int max_diff = 0; 211 for (int i = 0; i < kStride * height; ++i) { 212 int abs_diff = 213 abs(static_cast<int>(dst_argb_c[i]) - 214 static_cast<int>(dst_argb_opt[i])); 215 if (abs_diff > max_diff) { 216 max_diff = abs_diff; 217 } 218 } 219 free_aligned_buffer_64(src_argb); 220 free_aligned_buffer_64(dst_argb_c); 221 free_aligned_buffer_64(dst_argb_opt); 222 return max_diff; 223 } 224 225 TEST_F(libyuvTest, ARGBUnattenuate_Any) { 226 int max_diff = TestUnattenuateI(benchmark_width_ - 1, benchmark_height_, 227 benchmark_iterations_, +1, 0); 228 EXPECT_LE(max_diff, 2); 229 } 230 231 TEST_F(libyuvTest, ARGBUnattenuate_Unaligned) { 232 int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_, 233 benchmark_iterations_, +1, 1); 234 EXPECT_LE(max_diff, 2); 235 } 236 237 TEST_F(libyuvTest, ARGBUnattenuate_Invert) { 238 int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_, 239 benchmark_iterations_, -1, 0); 240 EXPECT_LE(max_diff, 2); 241 } 242 243 TEST_F(libyuvTest, ARGBUnattenuate_Opt) { 244 int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_, 245 benchmark_iterations_, +1, 0); 246 EXPECT_LE(max_diff, 2); 247 } 248 249 TEST_F(libyuvTest, TestARGBComputeCumulativeSum) { 250 SIMD_ALIGNED(uint8 orig_pixels[16][16][4]); 251 SIMD_ALIGNED(int32 added_pixels[16][16][4]); 252 253 for (int y = 0; y < 16; ++y) { 254 for (int x = 0; x < 16; ++x) { 255 orig_pixels[y][x][0] = 1u; 256 orig_pixels[y][x][1] = 2u; 257 orig_pixels[y][x][2] = 3u; 258 orig_pixels[y][x][3] = 255u; 259 } 260 } 261 262 ARGBComputeCumulativeSum(&orig_pixels[0][0][0], 16 * 4, 263 &added_pixels[0][0][0], 16 * 4, 264 16, 16); 265 266 for (int y = 0; y < 16; ++y) { 267 for (int x = 0; x < 16; ++x) { 268 EXPECT_EQ((x + 1) * (y + 1), added_pixels[y][x][0]); 269 EXPECT_EQ((x + 1) * (y + 1) * 2, added_pixels[y][x][1]); 270 EXPECT_EQ((x + 1) * (y + 1) * 3, added_pixels[y][x][2]); 271 EXPECT_EQ((x + 1) * (y + 1) * 255, added_pixels[y][x][3]); 272 } 273 } 274 } 275 276 TEST_F(libyuvTest, TestARGBGray) { 277 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 278 memset(orig_pixels, 0, sizeof(orig_pixels)); 279 280 // Test blue 281 orig_pixels[0][0] = 255u; 282 orig_pixels[0][1] = 0u; 283 orig_pixels[0][2] = 0u; 284 orig_pixels[0][3] = 128u; 285 // Test green 286 orig_pixels[1][0] = 0u; 287 orig_pixels[1][1] = 255u; 288 orig_pixels[1][2] = 0u; 289 orig_pixels[1][3] = 0u; 290 // Test red 291 orig_pixels[2][0] = 0u; 292 orig_pixels[2][1] = 0u; 293 orig_pixels[2][2] = 255u; 294 orig_pixels[2][3] = 255u; 295 // Test black 296 orig_pixels[3][0] = 0u; 297 orig_pixels[3][1] = 0u; 298 orig_pixels[3][2] = 0u; 299 orig_pixels[3][3] = 255u; 300 // Test white 301 orig_pixels[4][0] = 255u; 302 orig_pixels[4][1] = 255u; 303 orig_pixels[4][2] = 255u; 304 orig_pixels[4][3] = 255u; 305 // Test color 306 orig_pixels[5][0] = 16u; 307 orig_pixels[5][1] = 64u; 308 orig_pixels[5][2] = 192u; 309 orig_pixels[5][3] = 224u; 310 // Do 16 to test asm version. 311 ARGBGray(&orig_pixels[0][0], 0, 0, 0, 16, 1); 312 EXPECT_EQ(30u, orig_pixels[0][0]); 313 EXPECT_EQ(30u, orig_pixels[0][1]); 314 EXPECT_EQ(30u, orig_pixels[0][2]); 315 EXPECT_EQ(128u, orig_pixels[0][3]); 316 EXPECT_EQ(149u, orig_pixels[1][0]); 317 EXPECT_EQ(149u, orig_pixels[1][1]); 318 EXPECT_EQ(149u, orig_pixels[1][2]); 319 EXPECT_EQ(0u, orig_pixels[1][3]); 320 EXPECT_EQ(76u, orig_pixels[2][0]); 321 EXPECT_EQ(76u, orig_pixels[2][1]); 322 EXPECT_EQ(76u, orig_pixels[2][2]); 323 EXPECT_EQ(255u, orig_pixels[2][3]); 324 EXPECT_EQ(0u, orig_pixels[3][0]); 325 EXPECT_EQ(0u, orig_pixels[3][1]); 326 EXPECT_EQ(0u, orig_pixels[3][2]); 327 EXPECT_EQ(255u, orig_pixels[3][3]); 328 EXPECT_EQ(255u, orig_pixels[4][0]); 329 EXPECT_EQ(255u, orig_pixels[4][1]); 330 EXPECT_EQ(255u, orig_pixels[4][2]); 331 EXPECT_EQ(255u, orig_pixels[4][3]); 332 EXPECT_EQ(96u, orig_pixels[5][0]); 333 EXPECT_EQ(96u, orig_pixels[5][1]); 334 EXPECT_EQ(96u, orig_pixels[5][2]); 335 EXPECT_EQ(224u, orig_pixels[5][3]); 336 for (int i = 0; i < 1280; ++i) { 337 orig_pixels[i][0] = i; 338 orig_pixels[i][1] = i / 2; 339 orig_pixels[i][2] = i / 3; 340 orig_pixels[i][3] = i; 341 } 342 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 343 ARGBGray(&orig_pixels[0][0], 0, 0, 0, 1280, 1); 344 } 345 } 346 347 TEST_F(libyuvTest, TestARGBGrayTo) { 348 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 349 SIMD_ALIGNED(uint8 gray_pixels[1280][4]); 350 memset(orig_pixels, 0, sizeof(orig_pixels)); 351 352 // Test blue 353 orig_pixels[0][0] = 255u; 354 orig_pixels[0][1] = 0u; 355 orig_pixels[0][2] = 0u; 356 orig_pixels[0][3] = 128u; 357 // Test green 358 orig_pixels[1][0] = 0u; 359 orig_pixels[1][1] = 255u; 360 orig_pixels[1][2] = 0u; 361 orig_pixels[1][3] = 0u; 362 // Test red 363 orig_pixels[2][0] = 0u; 364 orig_pixels[2][1] = 0u; 365 orig_pixels[2][2] = 255u; 366 orig_pixels[2][3] = 255u; 367 // Test black 368 orig_pixels[3][0] = 0u; 369 orig_pixels[3][1] = 0u; 370 orig_pixels[3][2] = 0u; 371 orig_pixels[3][3] = 255u; 372 // Test white 373 orig_pixels[4][0] = 255u; 374 orig_pixels[4][1] = 255u; 375 orig_pixels[4][2] = 255u; 376 orig_pixels[4][3] = 255u; 377 // Test color 378 orig_pixels[5][0] = 16u; 379 orig_pixels[5][1] = 64u; 380 orig_pixels[5][2] = 192u; 381 orig_pixels[5][3] = 224u; 382 // Do 16 to test asm version. 383 ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 16, 1); 384 EXPECT_EQ(30u, gray_pixels[0][0]); 385 EXPECT_EQ(30u, gray_pixels[0][1]); 386 EXPECT_EQ(30u, gray_pixels[0][2]); 387 EXPECT_EQ(128u, gray_pixels[0][3]); 388 EXPECT_EQ(149u, gray_pixels[1][0]); 389 EXPECT_EQ(149u, gray_pixels[1][1]); 390 EXPECT_EQ(149u, gray_pixels[1][2]); 391 EXPECT_EQ(0u, gray_pixels[1][3]); 392 EXPECT_EQ(76u, gray_pixels[2][0]); 393 EXPECT_EQ(76u, gray_pixels[2][1]); 394 EXPECT_EQ(76u, gray_pixels[2][2]); 395 EXPECT_EQ(255u, gray_pixels[2][3]); 396 EXPECT_EQ(0u, gray_pixels[3][0]); 397 EXPECT_EQ(0u, gray_pixels[3][1]); 398 EXPECT_EQ(0u, gray_pixels[3][2]); 399 EXPECT_EQ(255u, gray_pixels[3][3]); 400 EXPECT_EQ(255u, gray_pixels[4][0]); 401 EXPECT_EQ(255u, gray_pixels[4][1]); 402 EXPECT_EQ(255u, gray_pixels[4][2]); 403 EXPECT_EQ(255u, gray_pixels[4][3]); 404 EXPECT_EQ(96u, gray_pixels[5][0]); 405 EXPECT_EQ(96u, gray_pixels[5][1]); 406 EXPECT_EQ(96u, gray_pixels[5][2]); 407 EXPECT_EQ(224u, gray_pixels[5][3]); 408 for (int i = 0; i < 1280; ++i) { 409 orig_pixels[i][0] = i; 410 orig_pixels[i][1] = i / 2; 411 orig_pixels[i][2] = i / 3; 412 orig_pixels[i][3] = i; 413 } 414 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 415 ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 1280, 1); 416 } 417 } 418 419 TEST_F(libyuvTest, TestARGBSepia) { 420 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 421 memset(orig_pixels, 0, sizeof(orig_pixels)); 422 423 // Test blue 424 orig_pixels[0][0] = 255u; 425 orig_pixels[0][1] = 0u; 426 orig_pixels[0][2] = 0u; 427 orig_pixels[0][3] = 128u; 428 // Test green 429 orig_pixels[1][0] = 0u; 430 orig_pixels[1][1] = 255u; 431 orig_pixels[1][2] = 0u; 432 orig_pixels[1][3] = 0u; 433 // Test red 434 orig_pixels[2][0] = 0u; 435 orig_pixels[2][1] = 0u; 436 orig_pixels[2][2] = 255u; 437 orig_pixels[2][3] = 255u; 438 // Test black 439 orig_pixels[3][0] = 0u; 440 orig_pixels[3][1] = 0u; 441 orig_pixels[3][2] = 0u; 442 orig_pixels[3][3] = 255u; 443 // Test white 444 orig_pixels[4][0] = 255u; 445 orig_pixels[4][1] = 255u; 446 orig_pixels[4][2] = 255u; 447 orig_pixels[4][3] = 255u; 448 // Test color 449 orig_pixels[5][0] = 16u; 450 orig_pixels[5][1] = 64u; 451 orig_pixels[5][2] = 192u; 452 orig_pixels[5][3] = 224u; 453 // Do 16 to test asm version. 454 ARGBSepia(&orig_pixels[0][0], 0, 0, 0, 16, 1); 455 EXPECT_EQ(33u, orig_pixels[0][0]); 456 EXPECT_EQ(43u, orig_pixels[0][1]); 457 EXPECT_EQ(47u, orig_pixels[0][2]); 458 EXPECT_EQ(128u, orig_pixels[0][3]); 459 EXPECT_EQ(135u, orig_pixels[1][0]); 460 EXPECT_EQ(175u, orig_pixels[1][1]); 461 EXPECT_EQ(195u, orig_pixels[1][2]); 462 EXPECT_EQ(0u, orig_pixels[1][3]); 463 EXPECT_EQ(69u, orig_pixels[2][0]); 464 EXPECT_EQ(89u, orig_pixels[2][1]); 465 EXPECT_EQ(99u, orig_pixels[2][2]); 466 EXPECT_EQ(255u, orig_pixels[2][3]); 467 EXPECT_EQ(0u, orig_pixels[3][0]); 468 EXPECT_EQ(0u, orig_pixels[3][1]); 469 EXPECT_EQ(0u, orig_pixels[3][2]); 470 EXPECT_EQ(255u, orig_pixels[3][3]); 471 EXPECT_EQ(239u, orig_pixels[4][0]); 472 EXPECT_EQ(255u, orig_pixels[4][1]); 473 EXPECT_EQ(255u, orig_pixels[4][2]); 474 EXPECT_EQ(255u, orig_pixels[4][3]); 475 EXPECT_EQ(88u, orig_pixels[5][0]); 476 EXPECT_EQ(114u, orig_pixels[5][1]); 477 EXPECT_EQ(127u, orig_pixels[5][2]); 478 EXPECT_EQ(224u, orig_pixels[5][3]); 479 480 for (int i = 0; i < 1280; ++i) { 481 orig_pixels[i][0] = i; 482 orig_pixels[i][1] = i / 2; 483 orig_pixels[i][2] = i / 3; 484 orig_pixels[i][3] = i; 485 } 486 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 487 ARGBSepia(&orig_pixels[0][0], 0, 0, 0, 1280, 1); 488 } 489 } 490 491 TEST_F(libyuvTest, TestARGBColorMatrix) { 492 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 493 SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); 494 SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); 495 496 // Matrix for Sepia. 497 SIMD_ALIGNED(static const int8 kRGBToSepia[]) = { 498 17 / 2, 68 / 2, 35 / 2, 0, 499 22 / 2, 88 / 2, 45 / 2, 0, 500 24 / 2, 98 / 2, 50 / 2, 0, 501 0, 0, 0, 64, // Copy alpha. 502 }; 503 memset(orig_pixels, 0, sizeof(orig_pixels)); 504 505 // Test blue 506 orig_pixels[0][0] = 255u; 507 orig_pixels[0][1] = 0u; 508 orig_pixels[0][2] = 0u; 509 orig_pixels[0][3] = 128u; 510 // Test green 511 orig_pixels[1][0] = 0u; 512 orig_pixels[1][1] = 255u; 513 orig_pixels[1][2] = 0u; 514 orig_pixels[1][3] = 0u; 515 // Test red 516 orig_pixels[2][0] = 0u; 517 orig_pixels[2][1] = 0u; 518 orig_pixels[2][2] = 255u; 519 orig_pixels[2][3] = 255u; 520 // Test color 521 orig_pixels[3][0] = 16u; 522 orig_pixels[3][1] = 64u; 523 orig_pixels[3][2] = 192u; 524 orig_pixels[3][3] = 224u; 525 // Do 16 to test asm version. 526 ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, 527 &kRGBToSepia[0], 16, 1); 528 EXPECT_EQ(31u, dst_pixels_opt[0][0]); 529 EXPECT_EQ(43u, dst_pixels_opt[0][1]); 530 EXPECT_EQ(47u, dst_pixels_opt[0][2]); 531 EXPECT_EQ(128u, dst_pixels_opt[0][3]); 532 EXPECT_EQ(135u, dst_pixels_opt[1][0]); 533 EXPECT_EQ(175u, dst_pixels_opt[1][1]); 534 EXPECT_EQ(195u, dst_pixels_opt[1][2]); 535 EXPECT_EQ(0u, dst_pixels_opt[1][3]); 536 EXPECT_EQ(67u, dst_pixels_opt[2][0]); 537 EXPECT_EQ(87u, dst_pixels_opt[2][1]); 538 EXPECT_EQ(99u, dst_pixels_opt[2][2]); 539 EXPECT_EQ(255u, dst_pixels_opt[2][3]); 540 EXPECT_EQ(87u, dst_pixels_opt[3][0]); 541 EXPECT_EQ(112u, dst_pixels_opt[3][1]); 542 EXPECT_EQ(127u, dst_pixels_opt[3][2]); 543 EXPECT_EQ(224u, dst_pixels_opt[3][3]); 544 545 for (int i = 0; i < 1280; ++i) { 546 orig_pixels[i][0] = i; 547 orig_pixels[i][1] = i / 2; 548 orig_pixels[i][2] = i / 3; 549 orig_pixels[i][3] = i; 550 } 551 MaskCpuFlags(0); 552 ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0, 553 &kRGBToSepia[0], 1280, 1); 554 MaskCpuFlags(-1); 555 556 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 557 ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, 558 &kRGBToSepia[0], 1280, 1); 559 } 560 561 for (int i = 0; i < 1280; ++i) { 562 EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]); 563 EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]); 564 EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]); 565 EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]); 566 } 567 } 568 569 TEST_F(libyuvTest, TestRGBColorMatrix) { 570 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 571 572 // Matrix for Sepia. 573 SIMD_ALIGNED(static const int8 kRGBToSepia[]) = { 574 17, 68, 35, 0, 575 22, 88, 45, 0, 576 24, 98, 50, 0, 577 0, 0, 0, 0, // Unused but makes matrix 16 bytes. 578 }; 579 memset(orig_pixels, 0, sizeof(orig_pixels)); 580 581 // Test blue 582 orig_pixels[0][0] = 255u; 583 orig_pixels[0][1] = 0u; 584 orig_pixels[0][2] = 0u; 585 orig_pixels[0][3] = 128u; 586 // Test green 587 orig_pixels[1][0] = 0u; 588 orig_pixels[1][1] = 255u; 589 orig_pixels[1][2] = 0u; 590 orig_pixels[1][3] = 0u; 591 // Test red 592 orig_pixels[2][0] = 0u; 593 orig_pixels[2][1] = 0u; 594 orig_pixels[2][2] = 255u; 595 orig_pixels[2][3] = 255u; 596 // Test color 597 orig_pixels[3][0] = 16u; 598 orig_pixels[3][1] = 64u; 599 orig_pixels[3][2] = 192u; 600 orig_pixels[3][3] = 224u; 601 // Do 16 to test asm version. 602 RGBColorMatrix(&orig_pixels[0][0], 0, &kRGBToSepia[0], 0, 0, 16, 1); 603 EXPECT_EQ(31u, orig_pixels[0][0]); 604 EXPECT_EQ(43u, orig_pixels[0][1]); 605 EXPECT_EQ(47u, orig_pixels[0][2]); 606 EXPECT_EQ(128u, orig_pixels[0][3]); 607 EXPECT_EQ(135u, orig_pixels[1][0]); 608 EXPECT_EQ(175u, orig_pixels[1][1]); 609 EXPECT_EQ(195u, orig_pixels[1][2]); 610 EXPECT_EQ(0u, orig_pixels[1][3]); 611 EXPECT_EQ(67u, orig_pixels[2][0]); 612 EXPECT_EQ(87u, orig_pixels[2][1]); 613 EXPECT_EQ(99u, orig_pixels[2][2]); 614 EXPECT_EQ(255u, orig_pixels[2][3]); 615 EXPECT_EQ(87u, orig_pixels[3][0]); 616 EXPECT_EQ(112u, orig_pixels[3][1]); 617 EXPECT_EQ(127u, orig_pixels[3][2]); 618 EXPECT_EQ(224u, orig_pixels[3][3]); 619 620 for (int i = 0; i < 1280; ++i) { 621 orig_pixels[i][0] = i; 622 orig_pixels[i][1] = i / 2; 623 orig_pixels[i][2] = i / 3; 624 orig_pixels[i][3] = i; 625 } 626 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 627 RGBColorMatrix(&orig_pixels[0][0], 0, &kRGBToSepia[0], 0, 0, 1280, 1); 628 } 629 } 630 631 TEST_F(libyuvTest, TestARGBColorTable) { 632 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 633 memset(orig_pixels, 0, sizeof(orig_pixels)); 634 635 // Matrix for Sepia. 636 static const uint8 kARGBTable[256 * 4] = { 637 1u, 2u, 3u, 4u, 638 5u, 6u, 7u, 8u, 639 9u, 10u, 11u, 12u, 640 13u, 14u, 15u, 16u, 641 }; 642 643 orig_pixels[0][0] = 0u; 644 orig_pixels[0][1] = 0u; 645 orig_pixels[0][2] = 0u; 646 orig_pixels[0][3] = 0u; 647 orig_pixels[1][0] = 1u; 648 orig_pixels[1][1] = 1u; 649 orig_pixels[1][2] = 1u; 650 orig_pixels[1][3] = 1u; 651 orig_pixels[2][0] = 2u; 652 orig_pixels[2][1] = 2u; 653 orig_pixels[2][2] = 2u; 654 orig_pixels[2][3] = 2u; 655 orig_pixels[3][0] = 0u; 656 orig_pixels[3][1] = 1u; 657 orig_pixels[3][2] = 2u; 658 orig_pixels[3][3] = 3u; 659 // Do 16 to test asm version. 660 ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1); 661 EXPECT_EQ(1u, orig_pixels[0][0]); 662 EXPECT_EQ(2u, orig_pixels[0][1]); 663 EXPECT_EQ(3u, orig_pixels[0][2]); 664 EXPECT_EQ(4u, orig_pixels[0][3]); 665 EXPECT_EQ(5u, orig_pixels[1][0]); 666 EXPECT_EQ(6u, orig_pixels[1][1]); 667 EXPECT_EQ(7u, orig_pixels[1][2]); 668 EXPECT_EQ(8u, orig_pixels[1][3]); 669 EXPECT_EQ(9u, orig_pixels[2][0]); 670 EXPECT_EQ(10u, orig_pixels[2][1]); 671 EXPECT_EQ(11u, orig_pixels[2][2]); 672 EXPECT_EQ(12u, orig_pixels[2][3]); 673 EXPECT_EQ(1u, orig_pixels[3][0]); 674 EXPECT_EQ(6u, orig_pixels[3][1]); 675 EXPECT_EQ(11u, orig_pixels[3][2]); 676 EXPECT_EQ(16u, orig_pixels[3][3]); 677 678 for (int i = 0; i < 1280; ++i) { 679 orig_pixels[i][0] = i; 680 orig_pixels[i][1] = i / 2; 681 orig_pixels[i][2] = i / 3; 682 orig_pixels[i][3] = i; 683 } 684 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 685 ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 1280, 1); 686 } 687 } 688 689 // Same as TestARGBColorTable except alpha does not change. 690 TEST_F(libyuvTest, TestRGBColorTable) { 691 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 692 memset(orig_pixels, 0, sizeof(orig_pixels)); 693 694 // Matrix for Sepia. 695 static const uint8 kARGBTable[256 * 4] = { 696 1u, 2u, 3u, 4u, 697 5u, 6u, 7u, 8u, 698 9u, 10u, 11u, 12u, 699 13u, 14u, 15u, 16u, 700 }; 701 702 orig_pixels[0][0] = 0u; 703 orig_pixels[0][1] = 0u; 704 orig_pixels[0][2] = 0u; 705 orig_pixels[0][3] = 0u; 706 orig_pixels[1][0] = 1u; 707 orig_pixels[1][1] = 1u; 708 orig_pixels[1][2] = 1u; 709 orig_pixels[1][3] = 1u; 710 orig_pixels[2][0] = 2u; 711 orig_pixels[2][1] = 2u; 712 orig_pixels[2][2] = 2u; 713 orig_pixels[2][3] = 2u; 714 orig_pixels[3][0] = 0u; 715 orig_pixels[3][1] = 1u; 716 orig_pixels[3][2] = 2u; 717 orig_pixels[3][3] = 3u; 718 // Do 16 to test asm version. 719 RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1); 720 EXPECT_EQ(1u, orig_pixels[0][0]); 721 EXPECT_EQ(2u, orig_pixels[0][1]); 722 EXPECT_EQ(3u, orig_pixels[0][2]); 723 EXPECT_EQ(0u, orig_pixels[0][3]); // Alpha unchanged. 724 EXPECT_EQ(5u, orig_pixels[1][0]); 725 EXPECT_EQ(6u, orig_pixels[1][1]); 726 EXPECT_EQ(7u, orig_pixels[1][2]); 727 EXPECT_EQ(1u, orig_pixels[1][3]); // Alpha unchanged. 728 EXPECT_EQ(9u, orig_pixels[2][0]); 729 EXPECT_EQ(10u, orig_pixels[2][1]); 730 EXPECT_EQ(11u, orig_pixels[2][2]); 731 EXPECT_EQ(2u, orig_pixels[2][3]); // Alpha unchanged. 732 EXPECT_EQ(1u, orig_pixels[3][0]); 733 EXPECT_EQ(6u, orig_pixels[3][1]); 734 EXPECT_EQ(11u, orig_pixels[3][2]); 735 EXPECT_EQ(3u, orig_pixels[3][3]); // Alpha unchanged. 736 737 for (int i = 0; i < 1280; ++i) { 738 orig_pixels[i][0] = i; 739 orig_pixels[i][1] = i / 2; 740 orig_pixels[i][2] = i / 3; 741 orig_pixels[i][3] = i; 742 } 743 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 744 RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 1280, 1); 745 } 746 } 747 748 TEST_F(libyuvTest, TestARGBQuantize) { 749 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 750 751 for (int i = 0; i < 1280; ++i) { 752 orig_pixels[i][0] = i; 753 orig_pixels[i][1] = i / 2; 754 orig_pixels[i][2] = i / 3; 755 orig_pixels[i][3] = i; 756 } 757 ARGBQuantize(&orig_pixels[0][0], 0, 758 (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0, 1280, 1); 759 760 for (int i = 0; i < 1280; ++i) { 761 EXPECT_EQ((i / 8 * 8 + 8 / 2) & 255, orig_pixels[i][0]); 762 EXPECT_EQ((i / 2 / 8 * 8 + 8 / 2) & 255, orig_pixels[i][1]); 763 EXPECT_EQ((i / 3 / 8 * 8 + 8 / 2) & 255, orig_pixels[i][2]); 764 EXPECT_EQ(i & 255, orig_pixels[i][3]); 765 } 766 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 767 ARGBQuantize(&orig_pixels[0][0], 0, 768 (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0, 1280, 1); 769 } 770 } 771 772 TEST_F(libyuvTest, TestARGBMirror) { 773 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 774 SIMD_ALIGNED(uint8 dst_pixels[1280][4]); 775 776 for (int i = 0; i < 1280; ++i) { 777 orig_pixels[i][0] = i; 778 orig_pixels[i][1] = i / 2; 779 orig_pixels[i][2] = i / 3; 780 orig_pixels[i][3] = i / 4; 781 } 782 ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 1280, 1); 783 784 for (int i = 0; i < 1280; ++i) { 785 EXPECT_EQ(i & 255, dst_pixels[1280 - 1 - i][0]); 786 EXPECT_EQ((i / 2) & 255, dst_pixels[1280 - 1 - i][1]); 787 EXPECT_EQ((i / 3) & 255, dst_pixels[1280 - 1 - i][2]); 788 EXPECT_EQ((i / 4) & 255, dst_pixels[1280 - 1 - i][3]); 789 } 790 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 791 ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 1280, 1); 792 } 793 } 794 795 TEST_F(libyuvTest, TestShade) { 796 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 797 SIMD_ALIGNED(uint8 shade_pixels[1280][4]); 798 memset(orig_pixels, 0, sizeof(orig_pixels)); 799 800 orig_pixels[0][0] = 10u; 801 orig_pixels[0][1] = 20u; 802 orig_pixels[0][2] = 40u; 803 orig_pixels[0][3] = 80u; 804 orig_pixels[1][0] = 0u; 805 orig_pixels[1][1] = 0u; 806 orig_pixels[1][2] = 0u; 807 orig_pixels[1][3] = 255u; 808 orig_pixels[2][0] = 0u; 809 orig_pixels[2][1] = 0u; 810 orig_pixels[2][2] = 0u; 811 orig_pixels[2][3] = 0u; 812 orig_pixels[3][0] = 0u; 813 orig_pixels[3][1] = 0u; 814 orig_pixels[3][2] = 0u; 815 orig_pixels[3][3] = 0u; 816 // Do 8 pixels to allow opt version to be used. 817 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x80ffffff); 818 EXPECT_EQ(10u, shade_pixels[0][0]); 819 EXPECT_EQ(20u, shade_pixels[0][1]); 820 EXPECT_EQ(40u, shade_pixels[0][2]); 821 EXPECT_EQ(40u, shade_pixels[0][3]); 822 EXPECT_EQ(0u, shade_pixels[1][0]); 823 EXPECT_EQ(0u, shade_pixels[1][1]); 824 EXPECT_EQ(0u, shade_pixels[1][2]); 825 EXPECT_EQ(128u, shade_pixels[1][3]); 826 EXPECT_EQ(0u, shade_pixels[2][0]); 827 EXPECT_EQ(0u, shade_pixels[2][1]); 828 EXPECT_EQ(0u, shade_pixels[2][2]); 829 EXPECT_EQ(0u, shade_pixels[2][3]); 830 EXPECT_EQ(0u, shade_pixels[3][0]); 831 EXPECT_EQ(0u, shade_pixels[3][1]); 832 EXPECT_EQ(0u, shade_pixels[3][2]); 833 EXPECT_EQ(0u, shade_pixels[3][3]); 834 835 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x80808080); 836 EXPECT_EQ(5u, shade_pixels[0][0]); 837 EXPECT_EQ(10u, shade_pixels[0][1]); 838 EXPECT_EQ(20u, shade_pixels[0][2]); 839 EXPECT_EQ(40u, shade_pixels[0][3]); 840 841 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x10204080); 842 EXPECT_EQ(5u, shade_pixels[0][0]); 843 EXPECT_EQ(5u, shade_pixels[0][1]); 844 EXPECT_EQ(5u, shade_pixels[0][2]); 845 EXPECT_EQ(5u, shade_pixels[0][3]); 846 847 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 848 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 1280, 1, 849 0x80808080); 850 } 851 } 852 853 TEST_F(libyuvTest, TestInterpolate) { 854 SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]); 855 SIMD_ALIGNED(uint8 orig_pixels_1[1280][4]); 856 SIMD_ALIGNED(uint8 interpolate_pixels[1280][4]); 857 memset(orig_pixels_0, 0, sizeof(orig_pixels_0)); 858 memset(orig_pixels_1, 0, sizeof(orig_pixels_1)); 859 860 orig_pixels_0[0][0] = 16u; 861 orig_pixels_0[0][1] = 32u; 862 orig_pixels_0[0][2] = 64u; 863 orig_pixels_0[0][3] = 128u; 864 orig_pixels_0[1][0] = 0u; 865 orig_pixels_0[1][1] = 0u; 866 orig_pixels_0[1][2] = 0u; 867 orig_pixels_0[1][3] = 255u; 868 orig_pixels_0[2][0] = 0u; 869 orig_pixels_0[2][1] = 0u; 870 orig_pixels_0[2][2] = 0u; 871 orig_pixels_0[2][3] = 0u; 872 orig_pixels_0[3][0] = 0u; 873 orig_pixels_0[3][1] = 0u; 874 orig_pixels_0[3][2] = 0u; 875 orig_pixels_0[3][3] = 0u; 876 877 orig_pixels_1[0][0] = 0u; 878 orig_pixels_1[0][1] = 0u; 879 orig_pixels_1[0][2] = 0u; 880 orig_pixels_1[0][3] = 0u; 881 orig_pixels_1[1][0] = 0u; 882 orig_pixels_1[1][1] = 0u; 883 orig_pixels_1[1][2] = 0u; 884 orig_pixels_1[1][3] = 0u; 885 orig_pixels_1[2][0] = 0u; 886 orig_pixels_1[2][1] = 0u; 887 orig_pixels_1[2][2] = 0u; 888 orig_pixels_1[2][3] = 0u; 889 orig_pixels_1[3][0] = 255u; 890 orig_pixels_1[3][1] = 255u; 891 orig_pixels_1[3][2] = 255u; 892 orig_pixels_1[3][3] = 255u; 893 894 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, 895 &interpolate_pixels[0][0], 0, 4, 1, 128); 896 EXPECT_EQ(8u, interpolate_pixels[0][0]); 897 EXPECT_EQ(16u, interpolate_pixels[0][1]); 898 EXPECT_EQ(32u, interpolate_pixels[0][2]); 899 EXPECT_EQ(64u, interpolate_pixels[0][3]); 900 EXPECT_EQ(0u, interpolate_pixels[1][0]); 901 EXPECT_EQ(0u, interpolate_pixels[1][1]); 902 EXPECT_EQ(0u, interpolate_pixels[1][2]); 903 EXPECT_NEAR(128u, interpolate_pixels[1][3], 1); // C = 127, SSE = 128. 904 EXPECT_EQ(0u, interpolate_pixels[2][0]); 905 EXPECT_EQ(0u, interpolate_pixels[2][1]); 906 EXPECT_EQ(0u, interpolate_pixels[2][2]); 907 EXPECT_EQ(0u, interpolate_pixels[2][3]); 908 EXPECT_NEAR(128u, interpolate_pixels[3][0], 1); 909 EXPECT_NEAR(128u, interpolate_pixels[3][1], 1); 910 EXPECT_NEAR(128u, interpolate_pixels[3][2], 1); 911 EXPECT_NEAR(128u, interpolate_pixels[3][3], 1); 912 913 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, 914 &interpolate_pixels[0][0], 0, 4, 1, 0); 915 EXPECT_EQ(16u, interpolate_pixels[0][0]); 916 EXPECT_EQ(32u, interpolate_pixels[0][1]); 917 EXPECT_EQ(64u, interpolate_pixels[0][2]); 918 EXPECT_EQ(128u, interpolate_pixels[0][3]); 919 920 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, 921 &interpolate_pixels[0][0], 0, 4, 1, 192); 922 923 EXPECT_EQ(4u, interpolate_pixels[0][0]); 924 EXPECT_EQ(8u, interpolate_pixels[0][1]); 925 EXPECT_EQ(16u, interpolate_pixels[0][2]); 926 EXPECT_EQ(32u, interpolate_pixels[0][3]); 927 928 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 929 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, 930 &interpolate_pixels[0][0], 0, 1280, 1, 128); 931 } 932 } 933 934 #define TESTTERP(FMT_A, BPP_A, STRIDE_A, \ 935 FMT_B, BPP_B, STRIDE_B, \ 936 W1280, TERP, DIFF, N, NEG, OFF) \ 937 TEST_F(libyuvTest, ARGBInterpolate##TERP##N) { \ 938 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 939 const int kHeight = benchmark_height_; \ 940 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \ 941 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \ 942 align_buffer_64(src_argb_a, kStrideA * kHeight + OFF); \ 943 align_buffer_64(src_argb_b, kStrideA * kHeight + OFF); \ 944 align_buffer_64(dst_argb_c, kStrideB * kHeight); \ 945 align_buffer_64(dst_argb_opt, kStrideB * kHeight); \ 946 srandom(time(NULL)); \ 947 for (int i = 0; i < kStrideA * kHeight; ++i) { \ 948 src_argb_a[i + OFF] = (random() & 0xff); \ 949 src_argb_b[i + OFF] = (random() & 0xff); \ 950 } \ 951 MaskCpuFlags(0); \ 952 ARGBInterpolate(src_argb_a + OFF, kStrideA, \ 953 src_argb_b + OFF, kStrideA, \ 954 dst_argb_c, kStrideB, \ 955 kWidth, NEG kHeight, TERP); \ 956 MaskCpuFlags(-1); \ 957 for (int i = 0; i < benchmark_iterations_; ++i) { \ 958 ARGBInterpolate(src_argb_a + OFF, kStrideA, \ 959 src_argb_b + OFF, kStrideA, \ 960 dst_argb_opt, kStrideB, \ 961 kWidth, NEG kHeight, TERP); \ 962 } \ 963 int max_diff = 0; \ 964 for (int i = 0; i < kStrideB * kHeight; ++i) { \ 965 int abs_diff = \ 966 abs(static_cast<int>(dst_argb_c[i]) - \ 967 static_cast<int>(dst_argb_opt[i])); \ 968 if (abs_diff > max_diff) { \ 969 max_diff = abs_diff; \ 970 } \ 971 } \ 972 EXPECT_LE(max_diff, DIFF); \ 973 free_aligned_buffer_64(src_argb_a); \ 974 free_aligned_buffer_64(src_argb_b); \ 975 free_aligned_buffer_64(dst_argb_c); \ 976 free_aligned_buffer_64(dst_argb_opt); \ 977 } 978 979 #define TESTINTERPOLATE(TERP) \ 980 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ 981 benchmark_width_ - 1, TERP, 1, _Any, +, 0) \ 982 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ 983 benchmark_width_, TERP, 1, _Unaligned, +, 1) \ 984 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ 985 benchmark_width_, TERP, 1, _Invert, -, 0) \ 986 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ 987 benchmark_width_, TERP, 1, _Opt, +, 0) \ 988 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ 989 benchmark_width_ - 1, TERP, 1, _Any_Invert, -, 0) 990 991 TESTINTERPOLATE(0) 992 TESTINTERPOLATE(64) 993 TESTINTERPOLATE(128) 994 TESTINTERPOLATE(192) 995 TESTINTERPOLATE(255) 996 997 static int TestBlend(int width, int height, int benchmark_iterations, 998 int invert, int off) { 999 if (width < 1) { 1000 width = 1; 1001 } 1002 const int kBpp = 4; 1003 const int kStride = width * kBpp; 1004 align_buffer_64(src_argb_a, kStride * height + off); 1005 align_buffer_64(src_argb_b, kStride * height + off); 1006 align_buffer_64(dst_argb_c, kStride * height); 1007 align_buffer_64(dst_argb_opt, kStride * height); 1008 srandom(time(NULL)); 1009 for (int i = 0; i < kStride * height; ++i) { 1010 src_argb_a[i + off] = (random() & 0xff); 1011 src_argb_b[i + off] = (random() & 0xff); 1012 } 1013 ARGBAttenuate(src_argb_a + off, kStride, src_argb_a + off, kStride, width, 1014 height); 1015 ARGBAttenuate(src_argb_b + off, kStride, src_argb_b + off, kStride, width, 1016 height); 1017 memset(dst_argb_c, 255, kStride * height); 1018 memset(dst_argb_opt, 255, kStride * height); 1019 1020 MaskCpuFlags(0); 1021 ARGBBlend(src_argb_a + off, kStride, 1022 src_argb_b + off, kStride, 1023 dst_argb_c, kStride, 1024 width, invert * height); 1025 MaskCpuFlags(-1); 1026 for (int i = 0; i < benchmark_iterations; ++i) { 1027 ARGBBlend(src_argb_a + off, kStride, 1028 src_argb_b + off, kStride, 1029 dst_argb_opt, kStride, 1030 width, invert * height); 1031 } 1032 int max_diff = 0; 1033 for (int i = 0; i < kStride * height; ++i) { 1034 int abs_diff = 1035 abs(static_cast<int>(dst_argb_c[i]) - 1036 static_cast<int>(dst_argb_opt[i])); 1037 if (abs_diff > max_diff) { 1038 max_diff = abs_diff; 1039 } 1040 } 1041 free_aligned_buffer_64(src_argb_a); 1042 free_aligned_buffer_64(src_argb_b); 1043 free_aligned_buffer_64(dst_argb_c); 1044 free_aligned_buffer_64(dst_argb_opt); 1045 return max_diff; 1046 } 1047 1048 TEST_F(libyuvTest, ARGBBlend_Any) { 1049 int max_diff = TestBlend(benchmark_width_ - 4, benchmark_height_, 1050 benchmark_iterations_, +1, 0); 1051 EXPECT_LE(max_diff, 1); 1052 } 1053 1054 TEST_F(libyuvTest, ARGBBlend_Unaligned) { 1055 int max_diff = TestBlend(benchmark_width_, benchmark_height_, 1056 benchmark_iterations_, +1, 1); 1057 EXPECT_LE(max_diff, 1); 1058 } 1059 1060 TEST_F(libyuvTest, ARGBBlend_Invert) { 1061 int max_diff = TestBlend(benchmark_width_, benchmark_height_, 1062 benchmark_iterations_, -1, 0); 1063 EXPECT_LE(max_diff, 1); 1064 } 1065 1066 TEST_F(libyuvTest, ARGBBlend_Opt) { 1067 int max_diff = TestBlend(benchmark_width_, benchmark_height_, 1068 benchmark_iterations_, +1, 0); 1069 EXPECT_LE(max_diff, 1); 1070 } 1071 1072 TEST_F(libyuvTest, TestAffine) { 1073 SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]); 1074 SIMD_ALIGNED(uint8 interpolate_pixels_C[1280][4]); 1075 1076 for (int i = 0; i < 1280; ++i) { 1077 for (int j = 0; j < 4; ++j) { 1078 orig_pixels_0[i][j] = i; 1079 } 1080 } 1081 1082 float uv_step[4] = { 0.f, 0.f, 0.75f, 0.f }; 1083 1084 ARGBAffineRow_C(&orig_pixels_0[0][0], 0, &interpolate_pixels_C[0][0], 1085 uv_step, 1280); 1086 EXPECT_EQ(0u, interpolate_pixels_C[0][0]); 1087 EXPECT_EQ(96u, interpolate_pixels_C[128][0]); 1088 EXPECT_EQ(191u, interpolate_pixels_C[255][3]); 1089 1090 #if defined(HAS_ARGBAFFINEROW_SSE2) 1091 SIMD_ALIGNED(uint8 interpolate_pixels_Opt[1280][4]); 1092 ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0], 1093 uv_step, 1280); 1094 EXPECT_EQ(0, memcmp(interpolate_pixels_Opt, interpolate_pixels_C, 1280 * 4)); 1095 1096 int has_sse2 = TestCpuFlag(kCpuHasSSE2); 1097 if (has_sse2) { 1098 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1099 ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0], 1100 uv_step, 1280); 1101 } 1102 } 1103 #endif 1104 } 1105 1106 TEST_F(libyuvTest, TestSobelX) { 1107 SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]); 1108 SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]); 1109 SIMD_ALIGNED(uint8 orig_pixels_2[1280 + 2]); 1110 SIMD_ALIGNED(uint8 sobel_pixels_c[1280]); 1111 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]); 1112 1113 for (int i = 0; i < 1280 + 2; ++i) { 1114 orig_pixels_0[i] = i; 1115 orig_pixels_1[i] = i * 2; 1116 orig_pixels_2[i] = i * 3; 1117 } 1118 1119 SobelXRow_C(orig_pixels_0, orig_pixels_1, orig_pixels_2, 1120 sobel_pixels_c, 1280); 1121 1122 EXPECT_EQ(16u, sobel_pixels_c[0]); 1123 EXPECT_EQ(16u, sobel_pixels_c[100]); 1124 EXPECT_EQ(255u, sobel_pixels_c[255]); 1125 1126 void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1, 1127 const uint8* src_y2, uint8* dst_sobely, int width) = 1128 SobelXRow_C; 1129 #if defined(HAS_SOBELXROW_SSE2) 1130 if (TestCpuFlag(kCpuHasSSE2)) { 1131 SobelXRow = SobelXRow_SSE2; 1132 } 1133 #endif 1134 #if defined(HAS_SOBELXROW_NEON) 1135 if (TestCpuFlag(kCpuHasNEON)) { 1136 SobelXRow = SobelXRow_NEON; 1137 } 1138 #endif 1139 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1140 SobelXRow(orig_pixels_0, orig_pixels_1, orig_pixels_2, 1141 sobel_pixels_opt, 1280); 1142 } 1143 for (int i = 0; i < 1280; ++i) { 1144 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); 1145 } 1146 } 1147 1148 TEST_F(libyuvTest, TestSobelY) { 1149 SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]); 1150 SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]); 1151 SIMD_ALIGNED(uint8 sobel_pixels_c[1280]); 1152 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]); 1153 1154 for (int i = 0; i < 1280 + 2; ++i) { 1155 orig_pixels_0[i] = i; 1156 orig_pixels_1[i] = i * 2; 1157 } 1158 1159 SobelYRow_C(orig_pixels_0, orig_pixels_1, sobel_pixels_c, 1280); 1160 1161 EXPECT_EQ(4u, sobel_pixels_c[0]); 1162 EXPECT_EQ(255u, sobel_pixels_c[100]); 1163 EXPECT_EQ(0u, sobel_pixels_c[255]); 1164 void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1, 1165 uint8* dst_sobely, int width) = SobelYRow_C; 1166 #if defined(HAS_SOBELYROW_SSE2) 1167 if (TestCpuFlag(kCpuHasSSE2)) { 1168 SobelYRow = SobelYRow_SSE2; 1169 } 1170 #endif 1171 #if defined(HAS_SOBELYROW_NEON) 1172 if (TestCpuFlag(kCpuHasNEON)) { 1173 SobelYRow = SobelYRow_NEON; 1174 } 1175 #endif 1176 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1177 SobelYRow(orig_pixels_0, orig_pixels_1, sobel_pixels_opt, 1280); 1178 } 1179 for (int i = 0; i < 1280; ++i) { 1180 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); 1181 } 1182 } 1183 1184 TEST_F(libyuvTest, TestSobel) { 1185 SIMD_ALIGNED(uint8 orig_sobelx[1280]); 1186 SIMD_ALIGNED(uint8 orig_sobely[1280]); 1187 SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]); 1188 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]); 1189 1190 for (int i = 0; i < 1280; ++i) { 1191 orig_sobelx[i] = i; 1192 orig_sobely[i] = i * 2; 1193 } 1194 1195 SobelRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280); 1196 1197 EXPECT_EQ(0u, sobel_pixels_c[0]); 1198 EXPECT_EQ(3u, sobel_pixels_c[4]); 1199 EXPECT_EQ(3u, sobel_pixels_c[5]); 1200 EXPECT_EQ(3u, sobel_pixels_c[6]); 1201 EXPECT_EQ(255u, sobel_pixels_c[7]); 1202 EXPECT_EQ(6u, sobel_pixels_c[8]); 1203 EXPECT_EQ(6u, sobel_pixels_c[9]); 1204 EXPECT_EQ(6u, sobel_pixels_c[10]); 1205 EXPECT_EQ(255u, sobel_pixels_c[7]); 1206 EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]); 1207 EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]); 1208 void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely, 1209 uint8* dst_argb, int width) = SobelRow_C; 1210 #if defined(HAS_SOBELROW_SSE2) 1211 if (TestCpuFlag(kCpuHasSSE2)) { 1212 SobelRow = SobelRow_SSE2; 1213 } 1214 #endif 1215 #if defined(HAS_SOBELROW_NEON) 1216 if (TestCpuFlag(kCpuHasNEON)) { 1217 SobelRow = SobelRow_NEON; 1218 } 1219 #endif 1220 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1221 SobelRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280); 1222 } 1223 for (int i = 0; i < 1280 * 4; ++i) { 1224 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); 1225 } 1226 } 1227 1228 TEST_F(libyuvTest, TestSobelToPlane) { 1229 SIMD_ALIGNED(uint8 orig_sobelx[1280]); 1230 SIMD_ALIGNED(uint8 orig_sobely[1280]); 1231 SIMD_ALIGNED(uint8 sobel_pixels_c[1280]); 1232 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]); 1233 1234 for (int i = 0; i < 1280; ++i) { 1235 orig_sobelx[i] = i; 1236 orig_sobely[i] = i * 2; 1237 } 1238 1239 SobelToPlaneRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280); 1240 1241 EXPECT_EQ(0u, sobel_pixels_c[0]); 1242 EXPECT_EQ(3u, sobel_pixels_c[1]); 1243 EXPECT_EQ(6u, sobel_pixels_c[2]); 1244 EXPECT_EQ(99u, sobel_pixels_c[33]); 1245 EXPECT_EQ(255u, sobel_pixels_c[100]); 1246 void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely, 1247 uint8* dst_y, int width) = SobelToPlaneRow_C; 1248 #if defined(HAS_SOBELTOPLANEROW_SSE2) 1249 if (TestCpuFlag(kCpuHasSSE2)) { 1250 SobelToPlaneRow = SobelToPlaneRow_SSE2; 1251 } 1252 #endif 1253 #if defined(HAS_SOBELTOPLANEROW_NEON) 1254 if (TestCpuFlag(kCpuHasNEON)) { 1255 SobelToPlaneRow = SobelToPlaneRow_NEON; 1256 } 1257 #endif 1258 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1259 SobelToPlaneRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280); 1260 } 1261 for (int i = 0; i < 1280; ++i) { 1262 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); 1263 } 1264 } 1265 1266 TEST_F(libyuvTest, TestSobelXY) { 1267 SIMD_ALIGNED(uint8 orig_sobelx[1280]); 1268 SIMD_ALIGNED(uint8 orig_sobely[1280]); 1269 SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]); 1270 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]); 1271 1272 for (int i = 0; i < 1280; ++i) { 1273 orig_sobelx[i] = i; 1274 orig_sobely[i] = i * 2; 1275 } 1276 1277 SobelXYRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280); 1278 1279 EXPECT_EQ(0u, sobel_pixels_c[0]); 1280 EXPECT_EQ(2u, sobel_pixels_c[4]); 1281 EXPECT_EQ(3u, sobel_pixels_c[5]); 1282 EXPECT_EQ(1u, sobel_pixels_c[6]); 1283 EXPECT_EQ(255u, sobel_pixels_c[7]); 1284 EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]); 1285 EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]); 1286 void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely, 1287 uint8* dst_argb, int width) = SobelXYRow_C; 1288 #if defined(HAS_SOBELXYROW_SSE2) 1289 if (TestCpuFlag(kCpuHasSSE2)) { 1290 SobelXYRow = SobelXYRow_SSE2; 1291 } 1292 #endif 1293 #if defined(HAS_SOBELXYROW_NEON) 1294 if (TestCpuFlag(kCpuHasNEON)) { 1295 SobelXYRow = SobelXYRow_NEON; 1296 } 1297 #endif 1298 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1299 SobelXYRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280); 1300 } 1301 for (int i = 0; i < 1280 * 4; ++i) { 1302 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); 1303 } 1304 } 1305 1306 TEST_F(libyuvTest, TestCopyPlane) { 1307 int err = 0; 1308 int yw = benchmark_width_; 1309 int yh = benchmark_height_; 1310 int b = 12; 1311 int i, j; 1312 1313 int y_plane_size = (yw + b * 2) * (yh + b * 2); 1314 srandom(time(NULL)); 1315 align_buffer_64(orig_y, y_plane_size); 1316 align_buffer_64(dst_c, y_plane_size); 1317 align_buffer_64(dst_opt, y_plane_size); 1318 1319 memset(orig_y, 0, y_plane_size); 1320 memset(dst_c, 0, y_plane_size); 1321 memset(dst_opt, 0, y_plane_size); 1322 1323 // Fill image buffers with random data. 1324 for (i = b; i < (yh + b); ++i) { 1325 for (j = b; j < (yw + b); ++j) { 1326 orig_y[i * (yw + b * 2) + j] = random() & 0xff; 1327 } 1328 } 1329 1330 // Fill destination buffers with random data. 1331 for (i = 0; i < y_plane_size; ++i) { 1332 uint8 random_number = random() & 0x7f; 1333 dst_c[i] = random_number; 1334 dst_opt[i] = dst_c[i]; 1335 } 1336 1337 int y_off = b * (yw + b * 2) + b; 1338 1339 int y_st = yw + b * 2; 1340 int stride = 8; 1341 1342 // Disable all optimizations. 1343 MaskCpuFlags(0); 1344 double c_time = get_time(); 1345 for (j = 0; j < benchmark_iterations_; j++) { 1346 CopyPlane(orig_y + y_off, y_st, dst_c + y_off, stride, yw, yh); 1347 } 1348 c_time = (get_time() - c_time) / benchmark_iterations_; 1349 1350 // Enable optimizations. 1351 MaskCpuFlags(-1); 1352 double opt_time = get_time(); 1353 for (j = 0; j < benchmark_iterations_; j++) { 1354 CopyPlane(orig_y + y_off, y_st, dst_opt + y_off, stride, yw, yh); 1355 } 1356 opt_time = (get_time() - opt_time) / benchmark_iterations_; 1357 1358 for (i = 0; i < y_plane_size; ++i) { 1359 if (dst_c[i] != dst_opt[i]) 1360 ++err; 1361 } 1362 1363 free_aligned_buffer_64(orig_y); 1364 free_aligned_buffer_64(dst_c); 1365 free_aligned_buffer_64(dst_opt); 1366 1367 EXPECT_EQ(0, err); 1368 } 1369 1370 static int TestMultiply(int width, int height, int benchmark_iterations, 1371 int invert, int off) { 1372 if (width < 1) { 1373 width = 1; 1374 } 1375 const int kBpp = 4; 1376 const int kStride = (width * kBpp + 15) & ~15; 1377 align_buffer_64(src_argb_a, kStride * height + off); 1378 align_buffer_64(src_argb_b, kStride * height + off); 1379 align_buffer_64(dst_argb_c, kStride * height); 1380 align_buffer_64(dst_argb_opt, kStride * height); 1381 srandom(time(NULL)); 1382 for (int i = 0; i < kStride * height; ++i) { 1383 src_argb_a[i + off] = (random() & 0xff); 1384 src_argb_b[i + off] = (random() & 0xff); 1385 } 1386 memset(dst_argb_c, 0, kStride * height); 1387 memset(dst_argb_opt, 0, kStride * height); 1388 1389 MaskCpuFlags(0); 1390 ARGBMultiply(src_argb_a + off, kStride, 1391 src_argb_b + off, kStride, 1392 dst_argb_c, kStride, 1393 width, invert * height); 1394 MaskCpuFlags(-1); 1395 for (int i = 0; i < benchmark_iterations; ++i) { 1396 ARGBMultiply(src_argb_a + off, kStride, 1397 src_argb_b + off, kStride, 1398 dst_argb_opt, kStride, 1399 width, invert * height); 1400 } 1401 int max_diff = 0; 1402 for (int i = 0; i < kStride * height; ++i) { 1403 int abs_diff = 1404 abs(static_cast<int>(dst_argb_c[i]) - 1405 static_cast<int>(dst_argb_opt[i])); 1406 if (abs_diff > max_diff) { 1407 max_diff = abs_diff; 1408 } 1409 } 1410 free_aligned_buffer_64(src_argb_a); 1411 free_aligned_buffer_64(src_argb_b); 1412 free_aligned_buffer_64(dst_argb_c); 1413 free_aligned_buffer_64(dst_argb_opt); 1414 return max_diff; 1415 } 1416 1417 TEST_F(libyuvTest, ARGBMultiply_Any) { 1418 int max_diff = TestMultiply(benchmark_width_ - 1, benchmark_height_, 1419 benchmark_iterations_, +1, 0); 1420 EXPECT_LE(max_diff, 1); 1421 } 1422 1423 TEST_F(libyuvTest, ARGBMultiply_Unaligned) { 1424 int max_diff = TestMultiply(benchmark_width_, benchmark_height_, 1425 benchmark_iterations_, +1, 1); 1426 EXPECT_LE(max_diff, 1); 1427 } 1428 1429 TEST_F(libyuvTest, ARGBMultiply_Invert) { 1430 int max_diff = TestMultiply(benchmark_width_, benchmark_height_, 1431 benchmark_iterations_, -1, 0); 1432 EXPECT_LE(max_diff, 1); 1433 } 1434 1435 TEST_F(libyuvTest, ARGBMultiply_Opt) { 1436 int max_diff = TestMultiply(benchmark_width_, benchmark_height_, 1437 benchmark_iterations_, +1, 0); 1438 EXPECT_LE(max_diff, 1); 1439 } 1440 1441 static int TestAdd(int width, int height, int benchmark_iterations, 1442 int invert, int off) { 1443 if (width < 1) { 1444 width = 1; 1445 } 1446 const int kBpp = 4; 1447 const int kStride = (width * kBpp + 15) & ~15; 1448 align_buffer_64(src_argb_a, kStride * height + off); 1449 align_buffer_64(src_argb_b, kStride * height + off); 1450 align_buffer_64(dst_argb_c, kStride * height); 1451 align_buffer_64(dst_argb_opt, kStride * height); 1452 srandom(time(NULL)); 1453 for (int i = 0; i < kStride * height; ++i) { 1454 src_argb_a[i + off] = (random() & 0xff); 1455 src_argb_b[i + off] = (random() & 0xff); 1456 } 1457 memset(dst_argb_c, 0, kStride * height); 1458 memset(dst_argb_opt, 0, kStride * height); 1459 1460 MaskCpuFlags(0); 1461 ARGBAdd(src_argb_a + off, kStride, 1462 src_argb_b + off, kStride, 1463 dst_argb_c, kStride, 1464 width, invert * height); 1465 MaskCpuFlags(-1); 1466 for (int i = 0; i < benchmark_iterations; ++i) { 1467 ARGBAdd(src_argb_a + off, kStride, 1468 src_argb_b + off, kStride, 1469 dst_argb_opt, kStride, 1470 width, invert * height); 1471 } 1472 int max_diff = 0; 1473 for (int i = 0; i < kStride * height; ++i) { 1474 int abs_diff = 1475 abs(static_cast<int>(dst_argb_c[i]) - 1476 static_cast<int>(dst_argb_opt[i])); 1477 if (abs_diff > max_diff) { 1478 max_diff = abs_diff; 1479 } 1480 } 1481 free_aligned_buffer_64(src_argb_a); 1482 free_aligned_buffer_64(src_argb_b); 1483 free_aligned_buffer_64(dst_argb_c); 1484 free_aligned_buffer_64(dst_argb_opt); 1485 return max_diff; 1486 } 1487 1488 TEST_F(libyuvTest, ARGBAdd_Any) { 1489 int max_diff = TestAdd(benchmark_width_ - 1, benchmark_height_, 1490 benchmark_iterations_, +1, 0); 1491 EXPECT_LE(max_diff, 1); 1492 } 1493 1494 TEST_F(libyuvTest, ARGBAdd_Unaligned) { 1495 int max_diff = TestAdd(benchmark_width_, benchmark_height_, 1496 benchmark_iterations_, +1, 1); 1497 EXPECT_LE(max_diff, 1); 1498 } 1499 1500 TEST_F(libyuvTest, ARGBAdd_Invert) { 1501 int max_diff = TestAdd(benchmark_width_, benchmark_height_, 1502 benchmark_iterations_, -1, 0); 1503 EXPECT_LE(max_diff, 1); 1504 } 1505 1506 TEST_F(libyuvTest, ARGBAdd_Opt) { 1507 int max_diff = TestAdd(benchmark_width_, benchmark_height_, 1508 benchmark_iterations_, +1, 0); 1509 EXPECT_LE(max_diff, 1); 1510 } 1511 1512 static int TestSubtract(int width, int height, int benchmark_iterations, 1513 int invert, int off) { 1514 if (width < 1) { 1515 width = 1; 1516 } 1517 const int kBpp = 4; 1518 const int kStride = (width * kBpp + 15) & ~15; 1519 align_buffer_64(src_argb_a, kStride * height + off); 1520 align_buffer_64(src_argb_b, kStride * height + off); 1521 align_buffer_64(dst_argb_c, kStride * height); 1522 align_buffer_64(dst_argb_opt, kStride * height); 1523 srandom(time(NULL)); 1524 for (int i = 0; i < kStride * height; ++i) { 1525 src_argb_a[i + off] = (random() & 0xff); 1526 src_argb_b[i + off] = (random() & 0xff); 1527 } 1528 memset(dst_argb_c, 0, kStride * height); 1529 memset(dst_argb_opt, 0, kStride * height); 1530 1531 MaskCpuFlags(0); 1532 ARGBSubtract(src_argb_a + off, kStride, 1533 src_argb_b + off, kStride, 1534 dst_argb_c, kStride, 1535 width, invert * height); 1536 MaskCpuFlags(-1); 1537 for (int i = 0; i < benchmark_iterations; ++i) { 1538 ARGBSubtract(src_argb_a + off, kStride, 1539 src_argb_b + off, kStride, 1540 dst_argb_opt, kStride, 1541 width, invert * height); 1542 } 1543 int max_diff = 0; 1544 for (int i = 0; i < kStride * height; ++i) { 1545 int abs_diff = 1546 abs(static_cast<int>(dst_argb_c[i]) - 1547 static_cast<int>(dst_argb_opt[i])); 1548 if (abs_diff > max_diff) { 1549 max_diff = abs_diff; 1550 } 1551 } 1552 free_aligned_buffer_64(src_argb_a); 1553 free_aligned_buffer_64(src_argb_b); 1554 free_aligned_buffer_64(dst_argb_c); 1555 free_aligned_buffer_64(dst_argb_opt); 1556 return max_diff; 1557 } 1558 1559 TEST_F(libyuvTest, ARGBSubtract_Any) { 1560 int max_diff = TestSubtract(benchmark_width_ - 1, benchmark_height_, 1561 benchmark_iterations_, +1, 0); 1562 EXPECT_LE(max_diff, 1); 1563 } 1564 1565 TEST_F(libyuvTest, ARGBSubtract_Unaligned) { 1566 int max_diff = TestSubtract(benchmark_width_, benchmark_height_, 1567 benchmark_iterations_, +1, 1); 1568 EXPECT_LE(max_diff, 1); 1569 } 1570 1571 TEST_F(libyuvTest, ARGBSubtract_Invert) { 1572 int max_diff = TestSubtract(benchmark_width_, benchmark_height_, 1573 benchmark_iterations_, -1, 0); 1574 EXPECT_LE(max_diff, 1); 1575 } 1576 1577 TEST_F(libyuvTest, ARGBSubtract_Opt) { 1578 int max_diff = TestSubtract(benchmark_width_, benchmark_height_, 1579 benchmark_iterations_, +1, 0); 1580 EXPECT_LE(max_diff, 1); 1581 } 1582 1583 static int TestSobel(int width, int height, int benchmark_iterations, 1584 int invert, int off) { 1585 if (width < 1) { 1586 width = 1; 1587 } 1588 const int kBpp = 4; 1589 const int kStride = (width * kBpp + 15) & ~15; 1590 align_buffer_64(src_argb_a, kStride * height + off); 1591 align_buffer_64(dst_argb_c, kStride * height); 1592 align_buffer_64(dst_argb_opt, kStride * height); 1593 memset(src_argb_a, 0, kStride * height + off); 1594 srandom(time(NULL)); 1595 for (int i = 0; i < kStride * height; ++i) { 1596 src_argb_a[i + off] = (random() & 0xff); 1597 } 1598 memset(dst_argb_c, 0, kStride * height); 1599 memset(dst_argb_opt, 0, kStride * height); 1600 1601 MaskCpuFlags(0); 1602 ARGBSobel(src_argb_a + off, kStride, 1603 dst_argb_c, kStride, 1604 width, invert * height); 1605 MaskCpuFlags(-1); 1606 for (int i = 0; i < benchmark_iterations; ++i) { 1607 ARGBSobel(src_argb_a + off, kStride, 1608 dst_argb_opt, kStride, 1609 width, invert * height); 1610 } 1611 int max_diff = 0; 1612 for (int i = 0; i < kStride * height; ++i) { 1613 int abs_diff = 1614 abs(static_cast<int>(dst_argb_c[i]) - 1615 static_cast<int>(dst_argb_opt[i])); 1616 if (abs_diff > max_diff) { 1617 max_diff = abs_diff; 1618 } 1619 } 1620 free_aligned_buffer_64(src_argb_a); 1621 free_aligned_buffer_64(dst_argb_c); 1622 free_aligned_buffer_64(dst_argb_opt); 1623 return max_diff; 1624 } 1625 1626 TEST_F(libyuvTest, ARGBSobel_Any) { 1627 int max_diff = TestSobel(benchmark_width_ - 1, benchmark_height_, 1628 benchmark_iterations_, +1, 0); 1629 EXPECT_EQ(0, max_diff); 1630 } 1631 1632 TEST_F(libyuvTest, ARGBSobel_Unaligned) { 1633 int max_diff = TestSobel(benchmark_width_, benchmark_height_, 1634 benchmark_iterations_, +1, 1); 1635 EXPECT_EQ(0, max_diff); 1636 } 1637 1638 TEST_F(libyuvTest, ARGBSobel_Invert) { 1639 int max_diff = TestSobel(benchmark_width_, benchmark_height_, 1640 benchmark_iterations_, -1, 0); 1641 EXPECT_EQ(0, max_diff); 1642 } 1643 1644 TEST_F(libyuvTest, ARGBSobel_Opt) { 1645 int max_diff = TestSobel(benchmark_width_, benchmark_height_, 1646 benchmark_iterations_, +1, 0); 1647 EXPECT_EQ(0, max_diff); 1648 } 1649 1650 static int TestSobelToPlane(int width, int height, int benchmark_iterations, 1651 int invert, int off) { 1652 if (width < 1) { 1653 width = 1; 1654 } 1655 const int kSrcBpp = 4; 1656 const int kDstBpp = 1; 1657 const int kSrcStride = (width * kSrcBpp + 15) & ~15; 1658 const int kDstStride = (width * kDstBpp + 15) & ~15; 1659 align_buffer_64(src_argb_a, kSrcStride * height + off); 1660 align_buffer_64(dst_argb_c, kDstStride * height); 1661 align_buffer_64(dst_argb_opt, kDstStride * height); 1662 memset(src_argb_a, 0, kSrcStride * height + off); 1663 srandom(time(NULL)); 1664 for (int i = 0; i < kSrcStride * height; ++i) { 1665 src_argb_a[i + off] = (random() & 0xff); 1666 } 1667 memset(dst_argb_c, 0, kDstStride * height); 1668 memset(dst_argb_opt, 0, kDstStride * height); 1669 1670 MaskCpuFlags(0); 1671 ARGBSobelToPlane(src_argb_a + off, kSrcStride, 1672 dst_argb_c, kDstStride, 1673 width, invert * height); 1674 MaskCpuFlags(-1); 1675 for (int i = 0; i < benchmark_iterations; ++i) { 1676 ARGBSobelToPlane(src_argb_a + off, kSrcStride, 1677 dst_argb_opt, kDstStride, 1678 width, invert * height); 1679 } 1680 int max_diff = 0; 1681 for (int i = 0; i < kDstStride * height; ++i) { 1682 int abs_diff = 1683 abs(static_cast<int>(dst_argb_c[i]) - 1684 static_cast<int>(dst_argb_opt[i])); 1685 if (abs_diff > max_diff) { 1686 max_diff = abs_diff; 1687 } 1688 } 1689 free_aligned_buffer_64(src_argb_a); 1690 free_aligned_buffer_64(dst_argb_c); 1691 free_aligned_buffer_64(dst_argb_opt); 1692 return max_diff; 1693 } 1694 1695 TEST_F(libyuvTest, ARGBSobelToPlane_Any) { 1696 int max_diff = TestSobelToPlane(benchmark_width_ - 1, benchmark_height_, 1697 benchmark_iterations_, +1, 0); 1698 EXPECT_EQ(0, max_diff); 1699 } 1700 1701 TEST_F(libyuvTest, ARGBSobelToPlane_Unaligned) { 1702 int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_, 1703 benchmark_iterations_, +1, 1); 1704 EXPECT_EQ(0, max_diff); 1705 } 1706 1707 TEST_F(libyuvTest, ARGBSobelToPlane_Invert) { 1708 int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_, 1709 benchmark_iterations_, -1, 0); 1710 EXPECT_EQ(0, max_diff); 1711 } 1712 1713 TEST_F(libyuvTest, ARGBSobelToPlane_Opt) { 1714 int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_, 1715 benchmark_iterations_, +1, 0); 1716 EXPECT_EQ(0, max_diff); 1717 } 1718 1719 static int TestSobelXY(int width, int height, int benchmark_iterations, 1720 int invert, int off) { 1721 if (width < 1) { 1722 width = 1; 1723 } 1724 const int kBpp = 4; 1725 const int kStride = (width * kBpp + 15) & ~15; 1726 align_buffer_64(src_argb_a, kStride * height + off); 1727 align_buffer_64(dst_argb_c, kStride * height); 1728 align_buffer_64(dst_argb_opt, kStride * height); 1729 memset(src_argb_a, 0, kStride * height + off); 1730 srandom(time(NULL)); 1731 for (int i = 0; i < kStride * height; ++i) { 1732 src_argb_a[i + off] = (random() & 0xff); 1733 } 1734 memset(dst_argb_c, 0, kStride * height); 1735 memset(dst_argb_opt, 0, kStride * height); 1736 1737 MaskCpuFlags(0); 1738 ARGBSobelXY(src_argb_a + off, kStride, 1739 dst_argb_c, kStride, 1740 width, invert * height); 1741 MaskCpuFlags(-1); 1742 for (int i = 0; i < benchmark_iterations; ++i) { 1743 ARGBSobelXY(src_argb_a + off, kStride, 1744 dst_argb_opt, kStride, 1745 width, invert * height); 1746 } 1747 int max_diff = 0; 1748 for (int i = 0; i < kStride * height; ++i) { 1749 int abs_diff = 1750 abs(static_cast<int>(dst_argb_c[i]) - 1751 static_cast<int>(dst_argb_opt[i])); 1752 if (abs_diff > max_diff) { 1753 max_diff = abs_diff; 1754 } 1755 } 1756 free_aligned_buffer_64(src_argb_a); 1757 free_aligned_buffer_64(dst_argb_c); 1758 free_aligned_buffer_64(dst_argb_opt); 1759 return max_diff; 1760 } 1761 1762 TEST_F(libyuvTest, ARGBSobelXY_Any) { 1763 int max_diff = TestSobelXY(benchmark_width_ - 1, benchmark_height_, 1764 benchmark_iterations_, +1, 0); 1765 EXPECT_EQ(0, max_diff); 1766 } 1767 1768 TEST_F(libyuvTest, ARGBSobelXY_Unaligned) { 1769 int max_diff = TestSobelXY(benchmark_width_, benchmark_height_, 1770 benchmark_iterations_, +1, 1); 1771 EXPECT_EQ(0, max_diff); 1772 } 1773 1774 TEST_F(libyuvTest, ARGBSobelXY_Invert) { 1775 int max_diff = TestSobelXY(benchmark_width_, benchmark_height_, 1776 benchmark_iterations_, -1, 0); 1777 EXPECT_EQ(0, max_diff); 1778 } 1779 1780 TEST_F(libyuvTest, ARGBSobelXY_Opt) { 1781 int max_diff = TestSobelXY(benchmark_width_, benchmark_height_, 1782 benchmark_iterations_, +1, 0); 1783 EXPECT_EQ(0, max_diff); 1784 } 1785 1786 static int TestBlur(int width, int height, int benchmark_iterations, 1787 int invert, int off, int radius) { 1788 if (width < 1) { 1789 width = 1; 1790 } 1791 const int kBpp = 4; 1792 const int kStride = (width * kBpp + 15) & ~15; 1793 align_buffer_64(src_argb_a, kStride * height + off); 1794 align_buffer_64(dst_cumsum, width * height * 16); 1795 align_buffer_64(dst_argb_c, kStride * height); 1796 align_buffer_64(dst_argb_opt, kStride * height); 1797 srandom(time(NULL)); 1798 for (int i = 0; i < kStride * height; ++i) { 1799 src_argb_a[i + off] = (random() & 0xff); 1800 } 1801 memset(dst_cumsum, 0, width * height * 16); 1802 memset(dst_argb_c, 0, kStride * height); 1803 memset(dst_argb_opt, 0, kStride * height); 1804 1805 MaskCpuFlags(0); 1806 ARGBBlur(src_argb_a + off, kStride, 1807 dst_argb_c, kStride, 1808 reinterpret_cast<int32*>(dst_cumsum), width * 4, 1809 width, invert * height, radius); 1810 MaskCpuFlags(-1); 1811 for (int i = 0; i < benchmark_iterations; ++i) { 1812 ARGBBlur(src_argb_a + off, kStride, 1813 dst_argb_opt, kStride, 1814 reinterpret_cast<int32*>(dst_cumsum), width * 4, 1815 width, invert * height, radius); 1816 } 1817 int max_diff = 0; 1818 for (int i = 0; i < kStride * height; ++i) { 1819 int abs_diff = 1820 abs(static_cast<int>(dst_argb_c[i]) - 1821 static_cast<int>(dst_argb_opt[i])); 1822 if (abs_diff > max_diff) { 1823 max_diff = abs_diff; 1824 } 1825 } 1826 free_aligned_buffer_64(src_argb_a); 1827 free_aligned_buffer_64(dst_cumsum); 1828 free_aligned_buffer_64(dst_argb_c); 1829 free_aligned_buffer_64(dst_argb_opt); 1830 return max_diff; 1831 } 1832 1833 static const int kBlurSize = 55; 1834 TEST_F(libyuvTest, ARGBBlur_Any) { 1835 int max_diff = TestBlur(benchmark_width_ - 1, benchmark_height_, 1836 benchmark_iterations_, +1, 0, kBlurSize); 1837 EXPECT_LE(max_diff, 1); 1838 } 1839 1840 TEST_F(libyuvTest, ARGBBlur_Unaligned) { 1841 int max_diff = TestBlur(benchmark_width_, benchmark_height_, 1842 benchmark_iterations_, +1, 1, kBlurSize); 1843 EXPECT_LE(max_diff, 1); 1844 } 1845 1846 TEST_F(libyuvTest, ARGBBlur_Invert) { 1847 int max_diff = TestBlur(benchmark_width_, benchmark_height_, 1848 benchmark_iterations_, -1, 0, kBlurSize); 1849 EXPECT_LE(max_diff, 1); 1850 } 1851 1852 TEST_F(libyuvTest, ARGBBlur_Opt) { 1853 int max_diff = TestBlur(benchmark_width_, benchmark_height_, 1854 benchmark_iterations_, +1, 0, kBlurSize); 1855 EXPECT_LE(max_diff, 1); 1856 } 1857 1858 static const int kBlurSmallSize = 5; 1859 TEST_F(libyuvTest, ARGBBlurSmall_Any) { 1860 int max_diff = TestBlur(benchmark_width_ - 1, benchmark_height_, 1861 benchmark_iterations_, +1, 0, kBlurSmallSize); 1862 EXPECT_LE(max_diff, 1); 1863 } 1864 1865 TEST_F(libyuvTest, ARGBBlurSmall_Unaligned) { 1866 int max_diff = TestBlur(benchmark_width_, benchmark_height_, 1867 benchmark_iterations_, +1, 1, kBlurSmallSize); 1868 EXPECT_LE(max_diff, 1); 1869 } 1870 1871 TEST_F(libyuvTest, ARGBBlurSmall_Invert) { 1872 int max_diff = TestBlur(benchmark_width_, benchmark_height_, 1873 benchmark_iterations_, -1, 0, kBlurSmallSize); 1874 EXPECT_LE(max_diff, 1); 1875 } 1876 1877 TEST_F(libyuvTest, ARGBBlurSmall_Opt) { 1878 int max_diff = TestBlur(benchmark_width_, benchmark_height_, 1879 benchmark_iterations_, +1, 0, kBlurSmallSize); 1880 EXPECT_LE(max_diff, 1); 1881 } 1882 1883 TEST_F(libyuvTest, TestARGBPolynomial) { 1884 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 1885 SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); 1886 SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); 1887 memset(orig_pixels, 0, sizeof(orig_pixels)); 1888 1889 SIMD_ALIGNED(static const float kWarmifyPolynomial[16]) = { 1890 0.94230f, -3.03300f, -2.92500f, 0.f, // C0 1891 0.584500f, 1.112000f, 1.535000f, 1.f, // C1 x 1892 0.001313f, -0.002503f, -0.004496f, 0.f, // C2 x * x 1893 0.0f, 0.000006965f, 0.000008781f, 0.f, // C3 x * x * x 1894 }; 1895 1896 // Test blue 1897 orig_pixels[0][0] = 255u; 1898 orig_pixels[0][1] = 0u; 1899 orig_pixels[0][2] = 0u; 1900 orig_pixels[0][3] = 128u; 1901 // Test green 1902 orig_pixels[1][0] = 0u; 1903 orig_pixels[1][1] = 255u; 1904 orig_pixels[1][2] = 0u; 1905 orig_pixels[1][3] = 0u; 1906 // Test red 1907 orig_pixels[2][0] = 0u; 1908 orig_pixels[2][1] = 0u; 1909 orig_pixels[2][2] = 255u; 1910 orig_pixels[2][3] = 255u; 1911 // Test white 1912 orig_pixels[3][0] = 255u; 1913 orig_pixels[3][1] = 255u; 1914 orig_pixels[3][2] = 255u; 1915 orig_pixels[3][3] = 255u; 1916 // Test color 1917 orig_pixels[4][0] = 16u; 1918 orig_pixels[4][1] = 64u; 1919 orig_pixels[4][2] = 192u; 1920 orig_pixels[4][3] = 224u; 1921 // Do 16 to test asm version. 1922 ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, 1923 &kWarmifyPolynomial[0], 16, 1); 1924 EXPECT_EQ(235u, dst_pixels_opt[0][0]); 1925 EXPECT_EQ(0u, dst_pixels_opt[0][1]); 1926 EXPECT_EQ(0u, dst_pixels_opt[0][2]); 1927 EXPECT_EQ(128u, dst_pixels_opt[0][3]); 1928 EXPECT_EQ(0u, dst_pixels_opt[1][0]); 1929 EXPECT_EQ(233u, dst_pixels_opt[1][1]); 1930 EXPECT_EQ(0u, dst_pixels_opt[1][2]); 1931 EXPECT_EQ(0u, dst_pixels_opt[1][3]); 1932 EXPECT_EQ(0u, dst_pixels_opt[2][0]); 1933 EXPECT_EQ(0u, dst_pixels_opt[2][1]); 1934 EXPECT_EQ(241u, dst_pixels_opt[2][2]); 1935 EXPECT_EQ(255u, dst_pixels_opt[2][3]); 1936 EXPECT_EQ(235u, dst_pixels_opt[3][0]); 1937 EXPECT_EQ(233u, dst_pixels_opt[3][1]); 1938 EXPECT_EQ(241u, dst_pixels_opt[3][2]); 1939 EXPECT_EQ(255u, dst_pixels_opt[3][3]); 1940 EXPECT_EQ(10u, dst_pixels_opt[4][0]); 1941 EXPECT_EQ(59u, dst_pixels_opt[4][1]); 1942 EXPECT_EQ(188u, dst_pixels_opt[4][2]); 1943 EXPECT_EQ(224u, dst_pixels_opt[4][3]); 1944 1945 for (int i = 0; i < 1280; ++i) { 1946 orig_pixels[i][0] = i; 1947 orig_pixels[i][1] = i / 2; 1948 orig_pixels[i][2] = i / 3; 1949 orig_pixels[i][3] = i; 1950 } 1951 1952 MaskCpuFlags(0); 1953 ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0, 1954 &kWarmifyPolynomial[0], 1280, 1); 1955 MaskCpuFlags(-1); 1956 1957 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 1958 ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, 1959 &kWarmifyPolynomial[0], 1280, 1); 1960 } 1961 1962 for (int i = 0; i < 1280; ++i) { 1963 EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]); 1964 EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]); 1965 EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]); 1966 EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]); 1967 } 1968 } 1969 1970 TEST_F(libyuvTest, TestARGBLumaColorTable) { 1971 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); 1972 SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); 1973 SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); 1974 memset(orig_pixels, 0, sizeof(orig_pixels)); 1975 1976 align_buffer_64(lumacolortable, 32768); 1977 int v = 0; 1978 for (int i = 0; i < 32768; ++i) { 1979 lumacolortable[i] = v; 1980 v += 3; 1981 } 1982 // Test blue 1983 orig_pixels[0][0] = 255u; 1984 orig_pixels[0][1] = 0u; 1985 orig_pixels[0][2] = 0u; 1986 orig_pixels[0][3] = 128u; 1987 // Test green 1988 orig_pixels[1][0] = 0u; 1989 orig_pixels[1][1] = 255u; 1990 orig_pixels[1][2] = 0u; 1991 orig_pixels[1][3] = 0u; 1992 // Test red 1993 orig_pixels[2][0] = 0u; 1994 orig_pixels[2][1] = 0u; 1995 orig_pixels[2][2] = 255u; 1996 orig_pixels[2][3] = 255u; 1997 // Test color 1998 orig_pixels[3][0] = 16u; 1999 orig_pixels[3][1] = 64u; 2000 orig_pixels[3][2] = 192u; 2001 orig_pixels[3][3] = 224u; 2002 // Do 16 to test asm version. 2003 ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, 2004 &lumacolortable[0], 16, 1); 2005 EXPECT_EQ(253u, dst_pixels_opt[0][0]); 2006 EXPECT_EQ(0u, dst_pixels_opt[0][1]); 2007 EXPECT_EQ(0u, dst_pixels_opt[0][2]); 2008 EXPECT_EQ(128u, dst_pixels_opt[0][3]); 2009 EXPECT_EQ(0u, dst_pixels_opt[1][0]); 2010 EXPECT_EQ(253u, dst_pixels_opt[1][1]); 2011 EXPECT_EQ(0u, dst_pixels_opt[1][2]); 2012 EXPECT_EQ(0u, dst_pixels_opt[1][3]); 2013 EXPECT_EQ(0u, dst_pixels_opt[2][0]); 2014 EXPECT_EQ(0u, dst_pixels_opt[2][1]); 2015 EXPECT_EQ(253u, dst_pixels_opt[2][2]); 2016 EXPECT_EQ(255u, dst_pixels_opt[2][3]); 2017 EXPECT_EQ(48u, dst_pixels_opt[3][0]); 2018 EXPECT_EQ(192u, dst_pixels_opt[3][1]); 2019 EXPECT_EQ(64u, dst_pixels_opt[3][2]); 2020 EXPECT_EQ(224u, dst_pixels_opt[3][3]); 2021 2022 for (int i = 0; i < 1280; ++i) { 2023 orig_pixels[i][0] = i; 2024 orig_pixels[i][1] = i / 2; 2025 orig_pixels[i][2] = i / 3; 2026 orig_pixels[i][3] = i; 2027 } 2028 2029 MaskCpuFlags(0); 2030 ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0, 2031 lumacolortable, 1280, 1); 2032 MaskCpuFlags(-1); 2033 2034 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { 2035 ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, 2036 lumacolortable, 1280, 1); 2037 } 2038 for (int i = 0; i < 1280; ++i) { 2039 EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]); 2040 EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]); 2041 EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]); 2042 EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]); 2043 } 2044 2045 free_aligned_buffer_64(lumacolortable); 2046 } 2047 2048 TEST_F(libyuvTest, TestARGBCopyAlpha) { 2049 const int kSize = benchmark_width_ * benchmark_height_ * 4; 2050 align_buffer_64(orig_pixels, kSize); 2051 align_buffer_64(dst_pixels_opt, kSize); 2052 align_buffer_64(dst_pixels_c, kSize); 2053 2054 MemRandomize(orig_pixels, kSize); 2055 MemRandomize(dst_pixels_opt, kSize); 2056 memcpy(dst_pixels_c, dst_pixels_opt, kSize); 2057 2058 MaskCpuFlags(0); 2059 ARGBCopyAlpha(orig_pixels, benchmark_width_ * 4, 2060 dst_pixels_c, benchmark_width_ * 4, 2061 benchmark_width_, benchmark_height_); 2062 MaskCpuFlags(-1); 2063 2064 for (int i = 0; i < benchmark_iterations_; ++i) { 2065 ARGBCopyAlpha(orig_pixels, benchmark_width_ * 4, 2066 dst_pixels_opt, benchmark_width_ * 4, 2067 benchmark_width_, benchmark_height_); 2068 } 2069 for (int i = 0; i < kSize; ++i) { 2070 EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]); 2071 } 2072 2073 free_aligned_buffer_64(dst_pixels_c); 2074 free_aligned_buffer_64(dst_pixels_opt); 2075 free_aligned_buffer_64(orig_pixels); 2076 } 2077 2078 TEST_F(libyuvTest, TestARGBCopyYToAlpha) { 2079 const int kPixels = benchmark_width_ * benchmark_height_; 2080 align_buffer_64(orig_pixels, kPixels); 2081 align_buffer_64(dst_pixels_opt, kPixels * 4); 2082 align_buffer_64(dst_pixels_c, kPixels * 4); 2083 2084 MemRandomize(orig_pixels, kPixels); 2085 MemRandomize(dst_pixels_opt, kPixels * 4); 2086 memcpy(dst_pixels_c, dst_pixels_opt, kPixels * 4); 2087 2088 MaskCpuFlags(0); 2089 ARGBCopyYToAlpha(orig_pixels, benchmark_width_, 2090 dst_pixels_c, benchmark_width_ * 4, 2091 benchmark_width_, benchmark_height_); 2092 MaskCpuFlags(-1); 2093 2094 for (int i = 0; i < benchmark_iterations_; ++i) { 2095 ARGBCopyYToAlpha(orig_pixels, benchmark_width_, 2096 dst_pixels_opt, benchmark_width_ * 4, 2097 benchmark_width_, benchmark_height_); 2098 } 2099 for (int i = 0; i < kPixels * 4; ++i) { 2100 EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]); 2101 } 2102 2103 free_aligned_buffer_64(dst_pixels_c); 2104 free_aligned_buffer_64(dst_pixels_opt); 2105 free_aligned_buffer_64(orig_pixels); 2106 } 2107 2108 } // namespace libyuv 2109