media/libyuv/unit_test/planar_test.cc

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial