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