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

     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  */
    11 #include <stdlib.h>
    12 #include <time.h>
    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"
    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
    32 namespace libyuv {
    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);
    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]);
    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]);
   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 }
   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);
   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 }
   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 }
   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 }
   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 }
   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 }
   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);
   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 }
   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 }
   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 }
   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 }
   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 }
   249 TEST_F(libyuvTest, TestARGBComputeCumulativeSum) {
   250   SIMD_ALIGNED(uint8 orig_pixels[16][16][4]);
   251   SIMD_ALIGNED(int32 added_pixels[16][16][4]);
   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   }
   262   ARGBComputeCumulativeSum(&orig_pixels[0][0][0], 16 * 4,
   263                            &added_pixels[0][0][0], 16 * 4,
   264                            16, 16);
   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 }
   276 TEST_F(libyuvTest, TestARGBGray) {
   277   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   278   memset(orig_pixels, 0, sizeof(orig_pixels));
   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 }
   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));
   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 }
   419 TEST_F(libyuvTest, TestARGBSepia) {
   420   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   421   memset(orig_pixels, 0, sizeof(orig_pixels));
   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]);
   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 }
   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]);
   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));
   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]);
   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);
   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   }
   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 }
   569 TEST_F(libyuvTest, TestRGBColorMatrix) {
   570   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   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));
   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]);
   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 }
   631 TEST_F(libyuvTest, TestARGBColorTable) {
   632   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   633   memset(orig_pixels, 0, sizeof(orig_pixels));
   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   };
   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]);
   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 }
   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));
   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   };
   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.
   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 }
   748 TEST_F(libyuvTest, TestARGBQuantize) {
   749   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   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);
   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 }
   772 TEST_F(libyuvTest, TestARGBMirror) {
   773   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   774   SIMD_ALIGNED(uint8 dst_pixels[1280][4]);
   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);
   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 }
   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));
   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]);
   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]);
   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]);
   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 }
   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));
   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;
   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;
   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);
   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]);
   920   ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
   921                   &interpolate_pixels[0][0], 0, 4, 1, 192);
   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]);
   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 }
   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 }
   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)
   991 TESTINTERPOLATE(0)
   992 TESTINTERPOLATE(64)
   993 TESTINTERPOLATE(128)
   994 TESTINTERPOLATE(192)
   995 TESTINTERPOLATE(255)
   997 static int TestBlend(int width, int height, int benchmark_iterations,
   998                      int invert, int off) {
   999   if (width < 1) {
  1000     width = 1;
  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);
  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);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  1072 TEST_F(libyuvTest, TestAffine) {
  1073   SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]);
  1074   SIMD_ALIGNED(uint8 interpolate_pixels_C[1280][4]);
  1076   for (int i = 0; i < 1280; ++i) {
  1077     for (int j = 0; j < 4; ++j) {
  1078       orig_pixels_0[i][j] = i;
  1082   float uv_step[4] = { 0.f, 0.f, 0.75f, 0.f };
  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]);
  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));
  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);
  1103 #endif
  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]);
  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;
  1119   SobelXRow_C(orig_pixels_0, orig_pixels_1, orig_pixels_2,
  1120               sobel_pixels_c, 1280);
  1122   EXPECT_EQ(16u, sobel_pixels_c[0]);
  1123   EXPECT_EQ(16u, sobel_pixels_c[100]);
  1124   EXPECT_EQ(255u, sobel_pixels_c[255]);
  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;
  1133 #endif
  1134 #if defined(HAS_SOBELXROW_NEON)
  1135   if (TestCpuFlag(kCpuHasNEON)) {
  1136     SobelXRow = SobelXRow_NEON;
  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);
  1143   for (int i = 0; i < 1280; ++i) {
  1144     EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
  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]);
  1154   for (int i = 0; i < 1280 + 2; ++i) {
  1155     orig_pixels_0[i] = i;
  1156     orig_pixels_1[i] = i * 2;
  1159   SobelYRow_C(orig_pixels_0, orig_pixels_1, sobel_pixels_c, 1280);
  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;
  1170 #endif
  1171 #if defined(HAS_SOBELYROW_NEON)
  1172   if (TestCpuFlag(kCpuHasNEON)) {
  1173     SobelYRow = SobelYRow_NEON;
  1175 #endif
  1176   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
  1177     SobelYRow(orig_pixels_0, orig_pixels_1, sobel_pixels_opt, 1280);
  1179   for (int i = 0; i < 1280; ++i) {
  1180     EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
  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]);
  1190   for (int i = 0; i < 1280; ++i) {
  1191     orig_sobelx[i] = i;
  1192     orig_sobely[i] = i * 2;
  1195   SobelRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
  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;
  1214 #endif
  1215 #if defined(HAS_SOBELROW_NEON)
  1216   if (TestCpuFlag(kCpuHasNEON)) {
  1217     SobelRow = SobelRow_NEON;
  1219 #endif
  1220   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
  1221     SobelRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
  1223   for (int i = 0; i < 1280 * 4; ++i) {
  1224     EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
  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]);
  1234   for (int i = 0; i < 1280; ++i) {
  1235     orig_sobelx[i] = i;
  1236     orig_sobely[i] = i * 2;
  1239   SobelToPlaneRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
  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;
  1252 #endif
  1253 #if defined(HAS_SOBELTOPLANEROW_NEON)
  1254   if (TestCpuFlag(kCpuHasNEON)) {
  1255     SobelToPlaneRow = SobelToPlaneRow_NEON;
  1257 #endif
  1258   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
  1259     SobelToPlaneRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
  1261   for (int i = 0; i < 1280; ++i) {
  1262     EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
  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]);
  1272   for (int i = 0; i < 1280; ++i) {
  1273     orig_sobelx[i] = i;
  1274     orig_sobely[i] = i * 2;
  1277   SobelXYRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
  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;
  1292 #endif
  1293 #if defined(HAS_SOBELXYROW_NEON)
  1294   if (TestCpuFlag(kCpuHasNEON)) {
  1295     SobelXYRow = SobelXYRow_NEON;
  1297 #endif
  1298   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
  1299     SobelXYRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
  1301   for (int i = 0; i < 1280 * 4; ++i) {
  1302     EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
  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;
  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);
  1319   memset(orig_y, 0, y_plane_size);
  1320   memset(dst_c, 0, y_plane_size);
  1321   memset(dst_opt, 0, y_plane_size);
  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;
  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];
  1337   int y_off = b * (yw + b * 2) + b;
  1339   int y_st = yw + b * 2;
  1340   int stride = 8;
  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);
  1348   c_time = (get_time() - c_time) / benchmark_iterations_;
  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);
  1356   opt_time = (get_time() - opt_time) / benchmark_iterations_;
  1358   for (i = 0; i < y_plane_size; ++i) {
  1359     if (dst_c[i] != dst_opt[i])
  1360       ++err;
  1363   free_aligned_buffer_64(orig_y);
  1364   free_aligned_buffer_64(dst_c);
  1365   free_aligned_buffer_64(dst_opt);
  1367   EXPECT_EQ(0, err);
  1370 static int TestMultiply(int width, int height, int benchmark_iterations,
  1371                         int invert, int off) {
  1372   if (width < 1) {
  1373     width = 1;
  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);
  1386   memset(dst_argb_c, 0, kStride * height);
  1387   memset(dst_argb_opt, 0, kStride * height);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  1441 static int TestAdd(int width, int height, int benchmark_iterations,
  1442                    int invert, int off) {
  1443   if (width < 1) {
  1444     width = 1;
  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);
  1457   memset(dst_argb_c, 0, kStride * height);
  1458   memset(dst_argb_opt, 0, kStride * height);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  1512 static int TestSubtract(int width, int height, int benchmark_iterations,
  1513                         int invert, int off) {
  1514   if (width < 1) {
  1515     width = 1;
  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);
  1528   memset(dst_argb_c, 0, kStride * height);
  1529   memset(dst_argb_opt, 0, kStride * height);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  1583 static int TestSobel(int width, int height, int benchmark_iterations,
  1584                      int invert, int off) {
  1585   if (width < 1) {
  1586     width = 1;
  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);
  1598   memset(dst_argb_c, 0, kStride * height);
  1599   memset(dst_argb_opt, 0, kStride * height);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  1650 static int TestSobelToPlane(int width, int height, int benchmark_iterations,
  1651                             int invert, int off) {
  1652   if (width < 1) {
  1653     width = 1;
  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);
  1667   memset(dst_argb_c, 0, kDstStride * height);
  1668   memset(dst_argb_opt, 0, kDstStride * height);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  1719 static int TestSobelXY(int width, int height, int benchmark_iterations,
  1720                      int invert, int off) {
  1721   if (width < 1) {
  1722     width = 1;
  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);
  1734   memset(dst_argb_c, 0, kStride * height);
  1735   memset(dst_argb_opt, 0, kStride * height);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  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;
  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);
  1801   memset(dst_cumsum, 0, width * height * 16);
  1802   memset(dst_argb_c, 0, kStride * height);
  1803   memset(dst_argb_opt, 0, kStride * height);
  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);
  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;
  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;
  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);
  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);
  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);
  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);
  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);
  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);
  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);
  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);
  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));
  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   };
  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]);
  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;
  1952   MaskCpuFlags(0);
  1953   ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0,
  1954                  &kWarmifyPolynomial[0], 1280, 1);
  1955   MaskCpuFlags(-1);
  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);
  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]);
  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));
  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;
  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]);
  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;
  2029   MaskCpuFlags(0);
  2030   ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0,
  2031                      lumacolortable, 1280, 1);
  2032   MaskCpuFlags(-1);
  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);
  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]);
  2045   free_aligned_buffer_64(lumacolortable);
  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);
  2054   MemRandomize(orig_pixels, kSize);
  2055   MemRandomize(dst_pixels_opt, kSize);
  2056   memcpy(dst_pixels_c, dst_pixels_opt, kSize);
  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);
  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_);
  2069   for (int i = 0; i < kSize; ++i) {
  2070     EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
  2073   free_aligned_buffer_64(dst_pixels_c);
  2074   free_aligned_buffer_64(dst_pixels_opt);
  2075   free_aligned_buffer_64(orig_pixels);
  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);
  2084   MemRandomize(orig_pixels, kPixels);
  2085   MemRandomize(dst_pixels_opt, kPixels * 4);
  2086   memcpy(dst_pixels_c, dst_pixels_opt, kPixels * 4);
  2088   MaskCpuFlags(0);
  2089   ARGBCopyYToAlpha(orig_pixels, benchmark_width_,
  2090                    dst_pixels_c, benchmark_width_ * 4,
  2091                    benchmark_width_, benchmark_height_);
  2092   MaskCpuFlags(-1);
  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_);
  2099   for (int i = 0; i < kPixels * 4; ++i) {
  2100     EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
  2103   free_aligned_buffer_64(dst_pixels_c);
  2104   free_aligned_buffer_64(dst_pixels_opt);
  2105   free_aligned_buffer_64(orig_pixels);
  2108 }  // namespace libyuv

mercurial