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 "../unit_test/unit_test.h"
     15 #include "libyuv/compare.h"
     16 #include "libyuv/convert.h"
     17 #include "libyuv/convert_argb.h"
     18 #include "libyuv/convert_from.h"
     19 #include "libyuv/convert_from_argb.h"
     20 #include "libyuv/cpu_id.h"
     21 #include "libyuv/planar_functions.h"
     22 #include "libyuv/rotate.h"
     23 
     24 namespace libyuv {
     25 
     26 TEST_F(LibYUVPlanarTest, TestAttenuate) {
     27   const int kSize = 1280 * 4;
     28   align_buffer_page_end(orig_pixels, kSize);
     29   align_buffer_page_end(atten_pixels, kSize);
     30   align_buffer_page_end(unatten_pixels, kSize);
     31   align_buffer_page_end(atten2_pixels, kSize);
     32 
     33   // Test unattenuation clamps
     34   orig_pixels[0 * 4 + 0] = 200u;
     35   orig_pixels[0 * 4 + 1] = 129u;
     36   orig_pixels[0 * 4 + 2] = 127u;
     37   orig_pixels[0 * 4 + 3] = 128u;
     38   // Test unattenuation transparent and opaque are unaffected
     39   orig_pixels[1 * 4 + 0] = 16u;
     40   orig_pixels[1 * 4 + 1] = 64u;
     41   orig_pixels[1 * 4 + 2] = 192u;
     42   orig_pixels[1 * 4 + 3] = 0u;
     43   orig_pixels[2 * 4 + 0] = 16u;
     44   orig_pixels[2 * 4 + 1] = 64u;
     45   orig_pixels[2 * 4 + 2] = 192u;
     46   orig_pixels[2 * 4 + 3] = 255u;
     47   orig_pixels[3 * 4 + 0] = 16u;
     48   orig_pixels[3 * 4 + 1] = 64u;
     49   orig_pixels[3 * 4 + 2] = 192u;
     50   orig_pixels[3 * 4 + 3] = 128u;
     51   ARGBUnattenuate(orig_pixels, 0, unatten_pixels, 0, 4, 1);
     52   EXPECT_EQ(255u, unatten_pixels[0 * 4 + 0]);
     53   EXPECT_EQ(255u, unatten_pixels[0 * 4 + 1]);
     54   EXPECT_EQ(254u, unatten_pixels[0 * 4 + 2]);
     55   EXPECT_EQ(128u, unatten_pixels[0 * 4 + 3]);
     56   EXPECT_EQ(0u, unatten_pixels[1 * 4 + 0]);
     57   EXPECT_EQ(0u, unatten_pixels[1 * 4 + 1]);
     58   EXPECT_EQ(0u, unatten_pixels[1 * 4 + 2]);
     59   EXPECT_EQ(0u, unatten_pixels[1 * 4 + 3]);
     60   EXPECT_EQ(16u, unatten_pixels[2 * 4 + 0]);
     61   EXPECT_EQ(64u, unatten_pixels[2 * 4 + 1]);
     62   EXPECT_EQ(192u, unatten_pixels[2 * 4 + 2]);
     63   EXPECT_EQ(255u, unatten_pixels[2 * 4 + 3]);
     64   EXPECT_EQ(32u, unatten_pixels[3 * 4 + 0]);
     65   EXPECT_EQ(128u, unatten_pixels[3 * 4 + 1]);
     66   EXPECT_EQ(255u, unatten_pixels[3 * 4 + 2]);
     67   EXPECT_EQ(128u, unatten_pixels[3 * 4 + 3]);
     68 
     69   for (int i = 0; i < 1280; ++i) {
     70     orig_pixels[i * 4 + 0] = i;
     71     orig_pixels[i * 4 + 1] = i / 2;
     72     orig_pixels[i * 4 + 2] = i / 3;
     73     orig_pixels[i * 4 + 3] = i;
     74   }
     75   ARGBAttenuate(orig_pixels, 0, atten_pixels, 0, 1280, 1);
     76   ARGBUnattenuate(atten_pixels, 0, unatten_pixels, 0, 1280, 1);
     77   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
     78     ARGBAttenuate(unatten_pixels, 0, atten2_pixels, 0, 1280, 1);
     79   }
     80   for (int i = 0; i < 1280; ++i) {
     81     EXPECT_NEAR(atten_pixels[i * 4 + 0], atten2_pixels[i * 4 + 0], 2);
     82     EXPECT_NEAR(atten_pixels[i * 4 + 1], atten2_pixels[i * 4 + 1], 2);
     83     EXPECT_NEAR(atten_pixels[i * 4 + 2], atten2_pixels[i * 4 + 2], 2);
     84     EXPECT_NEAR(atten_pixels[i * 4 + 3], atten2_pixels[i * 4 + 3], 2);
     85   }
     86   // Make sure transparent, 50% and opaque are fully accurate.
     87   EXPECT_EQ(0, atten_pixels[0 * 4 + 0]);
     88   EXPECT_EQ(0, atten_pixels[0 * 4 + 1]);
     89   EXPECT_EQ(0, atten_pixels[0 * 4 + 2]);
     90   EXPECT_EQ(0, atten_pixels[0 * 4 + 3]);
     91   EXPECT_EQ(64, atten_pixels[128 * 4 + 0]);
     92   EXPECT_EQ(32, atten_pixels[128 * 4 + 1]);
     93   EXPECT_EQ(21, atten_pixels[128 * 4 + 2]);
     94   EXPECT_EQ(128, atten_pixels[128 * 4 + 3]);
     95   EXPECT_NEAR(255, atten_pixels[255 * 4 + 0], 1);
     96   EXPECT_NEAR(127, atten_pixels[255 * 4 + 1], 1);
     97   EXPECT_NEAR(85, atten_pixels[255 * 4 + 2], 1);
     98   EXPECT_EQ(255, atten_pixels[255 * 4 + 3]);
     99 
    100   free_aligned_buffer_page_end(atten2_pixels);
    101   free_aligned_buffer_page_end(unatten_pixels);
    102   free_aligned_buffer_page_end(atten_pixels);
    103   free_aligned_buffer_page_end(orig_pixels);
    104 }
    105 
    106 static int TestAttenuateI(int width,
    107                           int height,
    108                           int benchmark_iterations,
    109                           int disable_cpu_flags,
    110                           int benchmark_cpu_info,
    111                           int invert,
    112                           int off) {
    113   if (width < 1) {
    114     width = 1;
    115   }
    116   const int kBpp = 4;
    117   const int kStride = width * kBpp;
    118   align_buffer_page_end(src_argb, kStride * height + off);
    119   align_buffer_page_end(dst_argb_c, kStride * height);
    120   align_buffer_page_end(dst_argb_opt, kStride * height);
    121   for (int i = 0; i < kStride * height; ++i) {
    122     src_argb[i + off] = (fastrand() & 0xff);
    123   }
    124   memset(dst_argb_c, 0, kStride * height);
    125   memset(dst_argb_opt, 0, kStride * height);
    126 
    127   MaskCpuFlags(disable_cpu_flags);
    128   ARGBAttenuate(src_argb + off, kStride, dst_argb_c, kStride, width,
    129                 invert * height);
    130   MaskCpuFlags(benchmark_cpu_info);
    131   for (int i = 0; i < benchmark_iterations; ++i) {
    132     ARGBAttenuate(src_argb + off, kStride, dst_argb_opt, kStride, width,
    133                   invert * height);
    134   }
    135   int max_diff = 0;
    136   for (int i = 0; i < kStride * height; ++i) {
    137     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
    138                        static_cast<int>(dst_argb_opt[i]));
    139     if (abs_diff > max_diff) {
    140       max_diff = abs_diff;
    141     }
    142   }
    143   free_aligned_buffer_page_end(src_argb);
    144   free_aligned_buffer_page_end(dst_argb_c);
    145   free_aligned_buffer_page_end(dst_argb_opt);
    146   return max_diff;
    147 }
    148 
    149 TEST_F(LibYUVPlanarTest, ARGBAttenuate_Any) {
    150   int max_diff = TestAttenuateI(benchmark_width_ - 1, benchmark_height_,
    151                                 benchmark_iterations_, disable_cpu_flags_,
    152                                 benchmark_cpu_info_, +1, 0);
    153   EXPECT_LE(max_diff, 2);
    154 }
    155 
    156 TEST_F(LibYUVPlanarTest, ARGBAttenuate_Unaligned) {
    157   int max_diff =
    158       TestAttenuateI(benchmark_width_, benchmark_height_, benchmark_iterations_,
    159                      disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
    160   EXPECT_LE(max_diff, 2);
    161 }
    162 
    163 TEST_F(LibYUVPlanarTest, ARGBAttenuate_Invert) {
    164   int max_diff =
    165       TestAttenuateI(benchmark_width_, benchmark_height_, benchmark_iterations_,
    166                      disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
    167   EXPECT_LE(max_diff, 2);
    168 }
    169 
    170 TEST_F(LibYUVPlanarTest, ARGBAttenuate_Opt) {
    171   int max_diff =
    172       TestAttenuateI(benchmark_width_, benchmark_height_, benchmark_iterations_,
    173                      disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
    174   EXPECT_LE(max_diff, 2);
    175 }
    176 
    177 static int TestUnattenuateI(int width,
    178                             int height,
    179                             int benchmark_iterations,
    180                             int disable_cpu_flags,
    181                             int benchmark_cpu_info,
    182                             int invert,
    183                             int off) {
    184   if (width < 1) {
    185     width = 1;
    186   }
    187   const int kBpp = 4;
    188   const int kStride = width * kBpp;
    189   align_buffer_page_end(src_argb, kStride * height + off);
    190   align_buffer_page_end(dst_argb_c, kStride * height);
    191   align_buffer_page_end(dst_argb_opt, kStride * height);
    192   for (int i = 0; i < kStride * height; ++i) {
    193     src_argb[i + off] = (fastrand() & 0xff);
    194   }
    195   ARGBAttenuate(src_argb + off, kStride, src_argb + off, kStride, width,
    196                 height);
    197   memset(dst_argb_c, 0, kStride * height);
    198   memset(dst_argb_opt, 0, kStride * height);
    199 
    200   MaskCpuFlags(disable_cpu_flags);
    201   ARGBUnattenuate(src_argb + off, kStride, dst_argb_c, kStride, width,
    202                   invert * height);
    203   MaskCpuFlags(benchmark_cpu_info);
    204   for (int i = 0; i < benchmark_iterations; ++i) {
    205     ARGBUnattenuate(src_argb + off, kStride, dst_argb_opt, kStride, width,
    206                     invert * height);
    207   }
    208   int max_diff = 0;
    209   for (int i = 0; i < kStride * height; ++i) {
    210     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
    211                        static_cast<int>(dst_argb_opt[i]));
    212     if (abs_diff > max_diff) {
    213       max_diff = abs_diff;
    214     }
    215   }
    216   free_aligned_buffer_page_end(src_argb);
    217   free_aligned_buffer_page_end(dst_argb_c);
    218   free_aligned_buffer_page_end(dst_argb_opt);
    219   return max_diff;
    220 }
    221 
    222 TEST_F(LibYUVPlanarTest, ARGBUnattenuate_Any) {
    223   int max_diff = TestUnattenuateI(benchmark_width_ - 1, benchmark_height_,
    224                                   benchmark_iterations_, disable_cpu_flags_,
    225                                   benchmark_cpu_info_, +1, 0);
    226   EXPECT_LE(max_diff, 2);
    227 }
    228 
    229 TEST_F(LibYUVPlanarTest, ARGBUnattenuate_Unaligned) {
    230   int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_,
    231                                   benchmark_iterations_, disable_cpu_flags_,
    232                                   benchmark_cpu_info_, +1, 1);
    233   EXPECT_LE(max_diff, 2);
    234 }
    235 
    236 TEST_F(LibYUVPlanarTest, ARGBUnattenuate_Invert) {
    237   int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_,
    238                                   benchmark_iterations_, disable_cpu_flags_,
    239                                   benchmark_cpu_info_, -1, 0);
    240   EXPECT_LE(max_diff, 2);
    241 }
    242 
    243 TEST_F(LibYUVPlanarTest, ARGBUnattenuate_Opt) {
    244   int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_,
    245                                   benchmark_iterations_, disable_cpu_flags_,
    246                                   benchmark_cpu_info_, +1, 0);
    247   EXPECT_LE(max_diff, 2);
    248 }
    249 
    250 TEST_F(LibYUVPlanarTest, TestARGBComputeCumulativeSum) {
    251   SIMD_ALIGNED(uint8 orig_pixels[16][16][4]);
    252   SIMD_ALIGNED(int32 added_pixels[16][16][4]);
    253 
    254   for (int y = 0; y < 16; ++y) {
    255     for (int x = 0; x < 16; ++x) {
    256       orig_pixels[y][x][0] = 1u;
    257       orig_pixels[y][x][1] = 2u;
    258       orig_pixels[y][x][2] = 3u;
    259       orig_pixels[y][x][3] = 255u;
    260     }
    261   }
    262 
    263   ARGBComputeCumulativeSum(&orig_pixels[0][0][0], 16 * 4,
    264                            &added_pixels[0][0][0], 16 * 4, 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(LibYUVPlanarTest, 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(LibYUVPlanarTest, 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(LibYUVPlanarTest, 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(LibYUVPlanarTest, 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, 22 / 2, 88 / 2, 45 / 2, 0,
    499       24 / 2, 98 / 2, 50 / 2, 0, 0,      0,      0,      64,  // Copy alpha.
    500   };
    501   memset(orig_pixels, 0, sizeof(orig_pixels));
    502 
    503   // Test blue
    504   orig_pixels[0][0] = 255u;
    505   orig_pixels[0][1] = 0u;
    506   orig_pixels[0][2] = 0u;
    507   orig_pixels[0][3] = 128u;
    508   // Test green
    509   orig_pixels[1][0] = 0u;
    510   orig_pixels[1][1] = 255u;
    511   orig_pixels[1][2] = 0u;
    512   orig_pixels[1][3] = 0u;
    513   // Test red
    514   orig_pixels[2][0] = 0u;
    515   orig_pixels[2][1] = 0u;
    516   orig_pixels[2][2] = 255u;
    517   orig_pixels[2][3] = 255u;
    518   // Test color
    519   orig_pixels[3][0] = 16u;
    520   orig_pixels[3][1] = 64u;
    521   orig_pixels[3][2] = 192u;
    522   orig_pixels[3][3] = 224u;
    523   // Do 16 to test asm version.
    524   ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0,
    525                   &kRGBToSepia[0], 16, 1);
    526   EXPECT_EQ(31u, dst_pixels_opt[0][0]);
    527   EXPECT_EQ(43u, dst_pixels_opt[0][1]);
    528   EXPECT_EQ(47u, dst_pixels_opt[0][2]);
    529   EXPECT_EQ(128u, dst_pixels_opt[0][3]);
    530   EXPECT_EQ(135u, dst_pixels_opt[1][0]);
    531   EXPECT_EQ(175u, dst_pixels_opt[1][1]);
    532   EXPECT_EQ(195u, dst_pixels_opt[1][2]);
    533   EXPECT_EQ(0u, dst_pixels_opt[1][3]);
    534   EXPECT_EQ(67u, dst_pixels_opt[2][0]);
    535   EXPECT_EQ(87u, dst_pixels_opt[2][1]);
    536   EXPECT_EQ(99u, dst_pixels_opt[2][2]);
    537   EXPECT_EQ(255u, dst_pixels_opt[2][3]);
    538   EXPECT_EQ(87u, dst_pixels_opt[3][0]);
    539   EXPECT_EQ(112u, dst_pixels_opt[3][1]);
    540   EXPECT_EQ(127u, dst_pixels_opt[3][2]);
    541   EXPECT_EQ(224u, dst_pixels_opt[3][3]);
    542 
    543   for (int i = 0; i < 1280; ++i) {
    544     orig_pixels[i][0] = i;
    545     orig_pixels[i][1] = i / 2;
    546     orig_pixels[i][2] = i / 3;
    547     orig_pixels[i][3] = i;
    548   }
    549   MaskCpuFlags(disable_cpu_flags_);
    550   ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0,
    551                   &kRGBToSepia[0], 1280, 1);
    552   MaskCpuFlags(benchmark_cpu_info_);
    553 
    554   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    555     ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0,
    556                     &kRGBToSepia[0], 1280, 1);
    557   }
    558 
    559   for (int i = 0; i < 1280; ++i) {
    560     EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]);
    561     EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]);
    562     EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]);
    563     EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]);
    564   }
    565 }
    566 
    567 TEST_F(LibYUVPlanarTest, TestRGBColorMatrix) {
    568   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
    569 
    570   // Matrix for Sepia.
    571   SIMD_ALIGNED(static const int8 kRGBToSepia[]) = {
    572       17, 68, 35, 0, 22, 88, 45, 0,
    573       24, 98, 50, 0, 0,  0,  0,  0,  // Unused but makes matrix 16 bytes.
    574   };
    575   memset(orig_pixels, 0, sizeof(orig_pixels));
    576 
    577   // Test blue
    578   orig_pixels[0][0] = 255u;
    579   orig_pixels[0][1] = 0u;
    580   orig_pixels[0][2] = 0u;
    581   orig_pixels[0][3] = 128u;
    582   // Test green
    583   orig_pixels[1][0] = 0u;
    584   orig_pixels[1][1] = 255u;
    585   orig_pixels[1][2] = 0u;
    586   orig_pixels[1][3] = 0u;
    587   // Test red
    588   orig_pixels[2][0] = 0u;
    589   orig_pixels[2][1] = 0u;
    590   orig_pixels[2][2] = 255u;
    591   orig_pixels[2][3] = 255u;
    592   // Test color
    593   orig_pixels[3][0] = 16u;
    594   orig_pixels[3][1] = 64u;
    595   orig_pixels[3][2] = 192u;
    596   orig_pixels[3][3] = 224u;
    597   // Do 16 to test asm version.
    598   RGBColorMatrix(&orig_pixels[0][0], 0, &kRGBToSepia[0], 0, 0, 16, 1);
    599   EXPECT_EQ(31u, orig_pixels[0][0]);
    600   EXPECT_EQ(43u, orig_pixels[0][1]);
    601   EXPECT_EQ(47u, orig_pixels[0][2]);
    602   EXPECT_EQ(128u, orig_pixels[0][3]);
    603   EXPECT_EQ(135u, orig_pixels[1][0]);
    604   EXPECT_EQ(175u, orig_pixels[1][1]);
    605   EXPECT_EQ(195u, orig_pixels[1][2]);
    606   EXPECT_EQ(0u, orig_pixels[1][3]);
    607   EXPECT_EQ(67u, orig_pixels[2][0]);
    608   EXPECT_EQ(87u, orig_pixels[2][1]);
    609   EXPECT_EQ(99u, orig_pixels[2][2]);
    610   EXPECT_EQ(255u, orig_pixels[2][3]);
    611   EXPECT_EQ(87u, orig_pixels[3][0]);
    612   EXPECT_EQ(112u, orig_pixels[3][1]);
    613   EXPECT_EQ(127u, orig_pixels[3][2]);
    614   EXPECT_EQ(224u, orig_pixels[3][3]);
    615 
    616   for (int i = 0; i < 1280; ++i) {
    617     orig_pixels[i][0] = i;
    618     orig_pixels[i][1] = i / 2;
    619     orig_pixels[i][2] = i / 3;
    620     orig_pixels[i][3] = i;
    621   }
    622   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    623     RGBColorMatrix(&orig_pixels[0][0], 0, &kRGBToSepia[0], 0, 0, 1280, 1);
    624   }
    625 }
    626 
    627 TEST_F(LibYUVPlanarTest, TestARGBColorTable) {
    628   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
    629   memset(orig_pixels, 0, sizeof(orig_pixels));
    630 
    631   // Matrix for Sepia.
    632   static const uint8 kARGBTable[256 * 4] = {
    633       1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u,
    634   };
    635 
    636   orig_pixels[0][0] = 0u;
    637   orig_pixels[0][1] = 0u;
    638   orig_pixels[0][2] = 0u;
    639   orig_pixels[0][3] = 0u;
    640   orig_pixels[1][0] = 1u;
    641   orig_pixels[1][1] = 1u;
    642   orig_pixels[1][2] = 1u;
    643   orig_pixels[1][3] = 1u;
    644   orig_pixels[2][0] = 2u;
    645   orig_pixels[2][1] = 2u;
    646   orig_pixels[2][2] = 2u;
    647   orig_pixels[2][3] = 2u;
    648   orig_pixels[3][0] = 0u;
    649   orig_pixels[3][1] = 1u;
    650   orig_pixels[3][2] = 2u;
    651   orig_pixels[3][3] = 3u;
    652   // Do 16 to test asm version.
    653   ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1);
    654   EXPECT_EQ(1u, orig_pixels[0][0]);
    655   EXPECT_EQ(2u, orig_pixels[0][1]);
    656   EXPECT_EQ(3u, orig_pixels[0][2]);
    657   EXPECT_EQ(4u, orig_pixels[0][3]);
    658   EXPECT_EQ(5u, orig_pixels[1][0]);
    659   EXPECT_EQ(6u, orig_pixels[1][1]);
    660   EXPECT_EQ(7u, orig_pixels[1][2]);
    661   EXPECT_EQ(8u, orig_pixels[1][3]);
    662   EXPECT_EQ(9u, orig_pixels[2][0]);
    663   EXPECT_EQ(10u, orig_pixels[2][1]);
    664   EXPECT_EQ(11u, orig_pixels[2][2]);
    665   EXPECT_EQ(12u, orig_pixels[2][3]);
    666   EXPECT_EQ(1u, orig_pixels[3][0]);
    667   EXPECT_EQ(6u, orig_pixels[3][1]);
    668   EXPECT_EQ(11u, orig_pixels[3][2]);
    669   EXPECT_EQ(16u, orig_pixels[3][3]);
    670 
    671   for (int i = 0; i < 1280; ++i) {
    672     orig_pixels[i][0] = i;
    673     orig_pixels[i][1] = i / 2;
    674     orig_pixels[i][2] = i / 3;
    675     orig_pixels[i][3] = i;
    676   }
    677   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    678     ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 1280, 1);
    679   }
    680 }
    681 
    682 // Same as TestARGBColorTable except alpha does not change.
    683 TEST_F(LibYUVPlanarTest, TestRGBColorTable) {
    684   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
    685   memset(orig_pixels, 0, sizeof(orig_pixels));
    686 
    687   // Matrix for Sepia.
    688   static const uint8 kARGBTable[256 * 4] = {
    689       1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u,
    690   };
    691 
    692   orig_pixels[0][0] = 0u;
    693   orig_pixels[0][1] = 0u;
    694   orig_pixels[0][2] = 0u;
    695   orig_pixels[0][3] = 0u;
    696   orig_pixels[1][0] = 1u;
    697   orig_pixels[1][1] = 1u;
    698   orig_pixels[1][2] = 1u;
    699   orig_pixels[1][3] = 1u;
    700   orig_pixels[2][0] = 2u;
    701   orig_pixels[2][1] = 2u;
    702   orig_pixels[2][2] = 2u;
    703   orig_pixels[2][3] = 2u;
    704   orig_pixels[3][0] = 0u;
    705   orig_pixels[3][1] = 1u;
    706   orig_pixels[3][2] = 2u;
    707   orig_pixels[3][3] = 3u;
    708   // Do 16 to test asm version.
    709   RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1);
    710   EXPECT_EQ(1u, orig_pixels[0][0]);
    711   EXPECT_EQ(2u, orig_pixels[0][1]);
    712   EXPECT_EQ(3u, orig_pixels[0][2]);
    713   EXPECT_EQ(0u, orig_pixels[0][3]);  // Alpha unchanged.
    714   EXPECT_EQ(5u, orig_pixels[1][0]);
    715   EXPECT_EQ(6u, orig_pixels[1][1]);
    716   EXPECT_EQ(7u, orig_pixels[1][2]);
    717   EXPECT_EQ(1u, orig_pixels[1][3]);  // Alpha unchanged.
    718   EXPECT_EQ(9u, orig_pixels[2][0]);
    719   EXPECT_EQ(10u, orig_pixels[2][1]);
    720   EXPECT_EQ(11u, orig_pixels[2][2]);
    721   EXPECT_EQ(2u, orig_pixels[2][3]);  // Alpha unchanged.
    722   EXPECT_EQ(1u, orig_pixels[3][0]);
    723   EXPECT_EQ(6u, orig_pixels[3][1]);
    724   EXPECT_EQ(11u, orig_pixels[3][2]);
    725   EXPECT_EQ(3u, orig_pixels[3][3]);  // Alpha unchanged.
    726 
    727   for (int i = 0; i < 1280; ++i) {
    728     orig_pixels[i][0] = i;
    729     orig_pixels[i][1] = i / 2;
    730     orig_pixels[i][2] = i / 3;
    731     orig_pixels[i][3] = i;
    732   }
    733   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    734     RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 1280, 1);
    735   }
    736 }
    737 
    738 TEST_F(LibYUVPlanarTest, TestARGBQuantize) {
    739   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
    740 
    741   for (int i = 0; i < 1280; ++i) {
    742     orig_pixels[i][0] = i;
    743     orig_pixels[i][1] = i / 2;
    744     orig_pixels[i][2] = i / 3;
    745     orig_pixels[i][3] = i;
    746   }
    747   ARGBQuantize(&orig_pixels[0][0], 0, (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0,
    748                1280, 1);
    749 
    750   for (int i = 0; i < 1280; ++i) {
    751     EXPECT_EQ((i / 8 * 8 + 8 / 2) & 255, orig_pixels[i][0]);
    752     EXPECT_EQ((i / 2 / 8 * 8 + 8 / 2) & 255, orig_pixels[i][1]);
    753     EXPECT_EQ((i / 3 / 8 * 8 + 8 / 2) & 255, orig_pixels[i][2]);
    754     EXPECT_EQ(i & 255, orig_pixels[i][3]);
    755   }
    756   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    757     ARGBQuantize(&orig_pixels[0][0], 0, (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0,
    758                  1280, 1);
    759   }
    760 }
    761 
    762 TEST_F(LibYUVPlanarTest, TestARGBMirror) {
    763   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
    764   SIMD_ALIGNED(uint8 dst_pixels[1280][4]);
    765 
    766   for (int i = 0; i < 1280; ++i) {
    767     orig_pixels[i][0] = i;
    768     orig_pixels[i][1] = i / 2;
    769     orig_pixels[i][2] = i / 3;
    770     orig_pixels[i][3] = i / 4;
    771   }
    772   ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 1280, 1);
    773 
    774   for (int i = 0; i < 1280; ++i) {
    775     EXPECT_EQ(i & 255, dst_pixels[1280 - 1 - i][0]);
    776     EXPECT_EQ((i / 2) & 255, dst_pixels[1280 - 1 - i][1]);
    777     EXPECT_EQ((i / 3) & 255, dst_pixels[1280 - 1 - i][2]);
    778     EXPECT_EQ((i / 4) & 255, dst_pixels[1280 - 1 - i][3]);
    779   }
    780   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    781     ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 1280, 1);
    782   }
    783 }
    784 
    785 TEST_F(LibYUVPlanarTest, TestShade) {
    786   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
    787   SIMD_ALIGNED(uint8 shade_pixels[1280][4]);
    788   memset(orig_pixels, 0, sizeof(orig_pixels));
    789 
    790   orig_pixels[0][0] = 10u;
    791   orig_pixels[0][1] = 20u;
    792   orig_pixels[0][2] = 40u;
    793   orig_pixels[0][3] = 80u;
    794   orig_pixels[1][0] = 0u;
    795   orig_pixels[1][1] = 0u;
    796   orig_pixels[1][2] = 0u;
    797   orig_pixels[1][3] = 255u;
    798   orig_pixels[2][0] = 0u;
    799   orig_pixels[2][1] = 0u;
    800   orig_pixels[2][2] = 0u;
    801   orig_pixels[2][3] = 0u;
    802   orig_pixels[3][0] = 0u;
    803   orig_pixels[3][1] = 0u;
    804   orig_pixels[3][2] = 0u;
    805   orig_pixels[3][3] = 0u;
    806   // Do 8 pixels to allow opt version to be used.
    807   ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x80ffffff);
    808   EXPECT_EQ(10u, shade_pixels[0][0]);
    809   EXPECT_EQ(20u, shade_pixels[0][1]);
    810   EXPECT_EQ(40u, shade_pixels[0][2]);
    811   EXPECT_EQ(40u, shade_pixels[0][3]);
    812   EXPECT_EQ(0u, shade_pixels[1][0]);
    813   EXPECT_EQ(0u, shade_pixels[1][1]);
    814   EXPECT_EQ(0u, shade_pixels[1][2]);
    815   EXPECT_EQ(128u, shade_pixels[1][3]);
    816   EXPECT_EQ(0u, shade_pixels[2][0]);
    817   EXPECT_EQ(0u, shade_pixels[2][1]);
    818   EXPECT_EQ(0u, shade_pixels[2][2]);
    819   EXPECT_EQ(0u, shade_pixels[2][3]);
    820   EXPECT_EQ(0u, shade_pixels[3][0]);
    821   EXPECT_EQ(0u, shade_pixels[3][1]);
    822   EXPECT_EQ(0u, shade_pixels[3][2]);
    823   EXPECT_EQ(0u, shade_pixels[3][3]);
    824 
    825   ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x80808080);
    826   EXPECT_EQ(5u, shade_pixels[0][0]);
    827   EXPECT_EQ(10u, shade_pixels[0][1]);
    828   EXPECT_EQ(20u, shade_pixels[0][2]);
    829   EXPECT_EQ(40u, shade_pixels[0][3]);
    830 
    831   ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x10204080);
    832   EXPECT_EQ(5u, shade_pixels[0][0]);
    833   EXPECT_EQ(5u, shade_pixels[0][1]);
    834   EXPECT_EQ(5u, shade_pixels[0][2]);
    835   EXPECT_EQ(5u, shade_pixels[0][3]);
    836 
    837   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    838     ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 1280, 1,
    839               0x80808080);
    840   }
    841 }
    842 
    843 TEST_F(LibYUVPlanarTest, TestARGBInterpolate) {
    844   SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]);
    845   SIMD_ALIGNED(uint8 orig_pixels_1[1280][4]);
    846   SIMD_ALIGNED(uint8 interpolate_pixels[1280][4]);
    847   memset(orig_pixels_0, 0, sizeof(orig_pixels_0));
    848   memset(orig_pixels_1, 0, sizeof(orig_pixels_1));
    849 
    850   orig_pixels_0[0][0] = 16u;
    851   orig_pixels_0[0][1] = 32u;
    852   orig_pixels_0[0][2] = 64u;
    853   orig_pixels_0[0][3] = 128u;
    854   orig_pixels_0[1][0] = 0u;
    855   orig_pixels_0[1][1] = 0u;
    856   orig_pixels_0[1][2] = 0u;
    857   orig_pixels_0[1][3] = 255u;
    858   orig_pixels_0[2][0] = 0u;
    859   orig_pixels_0[2][1] = 0u;
    860   orig_pixels_0[2][2] = 0u;
    861   orig_pixels_0[2][3] = 0u;
    862   orig_pixels_0[3][0] = 0u;
    863   orig_pixels_0[3][1] = 0u;
    864   orig_pixels_0[3][2] = 0u;
    865   orig_pixels_0[3][3] = 0u;
    866 
    867   orig_pixels_1[0][0] = 0u;
    868   orig_pixels_1[0][1] = 0u;
    869   orig_pixels_1[0][2] = 0u;
    870   orig_pixels_1[0][3] = 0u;
    871   orig_pixels_1[1][0] = 0u;
    872   orig_pixels_1[1][1] = 0u;
    873   orig_pixels_1[1][2] = 0u;
    874   orig_pixels_1[1][3] = 0u;
    875   orig_pixels_1[2][0] = 0u;
    876   orig_pixels_1[2][1] = 0u;
    877   orig_pixels_1[2][2] = 0u;
    878   orig_pixels_1[2][3] = 0u;
    879   orig_pixels_1[3][0] = 255u;
    880   orig_pixels_1[3][1] = 255u;
    881   orig_pixels_1[3][2] = 255u;
    882   orig_pixels_1[3][3] = 255u;
    883 
    884   ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
    885                   &interpolate_pixels[0][0], 0, 4, 1, 128);
    886   EXPECT_EQ(8u, interpolate_pixels[0][0]);
    887   EXPECT_EQ(16u, interpolate_pixels[0][1]);
    888   EXPECT_EQ(32u, interpolate_pixels[0][2]);
    889   EXPECT_EQ(64u, interpolate_pixels[0][3]);
    890   EXPECT_EQ(0u, interpolate_pixels[1][0]);
    891   EXPECT_EQ(0u, interpolate_pixels[1][1]);
    892   EXPECT_EQ(0u, interpolate_pixels[1][2]);
    893   EXPECT_EQ(128u, interpolate_pixels[1][3]);
    894   EXPECT_EQ(0u, interpolate_pixels[2][0]);
    895   EXPECT_EQ(0u, interpolate_pixels[2][1]);
    896   EXPECT_EQ(0u, interpolate_pixels[2][2]);
    897   EXPECT_EQ(0u, interpolate_pixels[2][3]);
    898   EXPECT_EQ(128u, interpolate_pixels[3][0]);
    899   EXPECT_EQ(128u, interpolate_pixels[3][1]);
    900   EXPECT_EQ(128u, interpolate_pixels[3][2]);
    901   EXPECT_EQ(128u, interpolate_pixels[3][3]);
    902 
    903   ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
    904                   &interpolate_pixels[0][0], 0, 4, 1, 0);
    905   EXPECT_EQ(16u, interpolate_pixels[0][0]);
    906   EXPECT_EQ(32u, interpolate_pixels[0][1]);
    907   EXPECT_EQ(64u, interpolate_pixels[0][2]);
    908   EXPECT_EQ(128u, interpolate_pixels[0][3]);
    909 
    910   ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
    911                   &interpolate_pixels[0][0], 0, 4, 1, 192);
    912 
    913   EXPECT_EQ(4u, interpolate_pixels[0][0]);
    914   EXPECT_EQ(8u, interpolate_pixels[0][1]);
    915   EXPECT_EQ(16u, interpolate_pixels[0][2]);
    916   EXPECT_EQ(32u, interpolate_pixels[0][3]);
    917 
    918   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
    919     ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
    920                     &interpolate_pixels[0][0], 0, 1280, 1, 128);
    921   }
    922 }
    923 
    924 TEST_F(LibYUVPlanarTest, TestInterpolatePlane) {
    925   SIMD_ALIGNED(uint8 orig_pixels_0[1280]);
    926   SIMD_ALIGNED(uint8 orig_pixels_1[1280]);
    927   SIMD_ALIGNED(uint8 interpolate_pixels[1280]);
    928   memset(orig_pixels_0, 0, sizeof(orig_pixels_0));
    929   memset(orig_pixels_1, 0, sizeof(orig_pixels_1));
    930 
    931   orig_pixels_0[0] = 16u;
    932   orig_pixels_0[1] = 32u;
    933   orig_pixels_0[2] = 64u;
    934   orig_pixels_0[3] = 128u;
    935   orig_pixels_0[4] = 0u;
    936   orig_pixels_0[5] = 0u;
    937   orig_pixels_0[6] = 0u;
    938   orig_pixels_0[7] = 255u;
    939   orig_pixels_0[8] = 0u;
    940   orig_pixels_0[9] = 0u;
    941   orig_pixels_0[10] = 0u;
    942   orig_pixels_0[11] = 0u;
    943   orig_pixels_0[12] = 0u;
    944   orig_pixels_0[13] = 0u;
    945   orig_pixels_0[14] = 0u;
    946   orig_pixels_0[15] = 0u;
    947 
    948   orig_pixels_1[0] = 0u;
    949   orig_pixels_1[1] = 0u;
    950   orig_pixels_1[2] = 0u;
    951   orig_pixels_1[3] = 0u;
    952   orig_pixels_1[4] = 0u;
    953   orig_pixels_1[5] = 0u;
    954   orig_pixels_1[6] = 0u;
    955   orig_pixels_1[7] = 0u;
    956   orig_pixels_1[8] = 0u;
    957   orig_pixels_1[9] = 0u;
    958   orig_pixels_1[10] = 0u;
    959   orig_pixels_1[11] = 0u;
    960   orig_pixels_1[12] = 255u;
    961   orig_pixels_1[13] = 255u;
    962   orig_pixels_1[14] = 255u;
    963   orig_pixels_1[15] = 255u;
    964 
    965   InterpolatePlane(&orig_pixels_0[0], 0, &orig_pixels_1[0], 0,
    966                    &interpolate_pixels[0], 0, 16, 1, 128);
    967   EXPECT_EQ(8u, interpolate_pixels[0]);
    968   EXPECT_EQ(16u, interpolate_pixels[1]);
    969   EXPECT_EQ(32u, interpolate_pixels[2]);
    970   EXPECT_EQ(64u, interpolate_pixels[3]);
    971   EXPECT_EQ(0u, interpolate_pixels[4]);
    972   EXPECT_EQ(0u, interpolate_pixels[5]);
    973   EXPECT_EQ(0u, interpolate_pixels[6]);
    974   EXPECT_EQ(128u, interpolate_pixels[7]);
    975   EXPECT_EQ(0u, interpolate_pixels[8]);
    976   EXPECT_EQ(0u, interpolate_pixels[9]);
    977   EXPECT_EQ(0u, interpolate_pixels[10]);
    978   EXPECT_EQ(0u, interpolate_pixels[11]);
    979   EXPECT_EQ(128u, interpolate_pixels[12]);
    980   EXPECT_EQ(128u, interpolate_pixels[13]);
    981   EXPECT_EQ(128u, interpolate_pixels[14]);
    982   EXPECT_EQ(128u, interpolate_pixels[15]);
    983 
    984   InterpolatePlane(&orig_pixels_0[0], 0, &orig_pixels_1[0], 0,
    985                    &interpolate_pixels[0], 0, 16, 1, 0);
    986   EXPECT_EQ(16u, interpolate_pixels[0]);
    987   EXPECT_EQ(32u, interpolate_pixels[1]);
    988   EXPECT_EQ(64u, interpolate_pixels[2]);
    989   EXPECT_EQ(128u, interpolate_pixels[3]);
    990 
    991   InterpolatePlane(&orig_pixels_0[0], 0, &orig_pixels_1[0], 0,
    992                    &interpolate_pixels[0], 0, 16, 1, 192);
    993 
    994   EXPECT_EQ(4u, interpolate_pixels[0]);
    995   EXPECT_EQ(8u, interpolate_pixels[1]);
    996   EXPECT_EQ(16u, interpolate_pixels[2]);
    997   EXPECT_EQ(32u, interpolate_pixels[3]);
    998 
    999   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
   1000     InterpolatePlane(&orig_pixels_0[0], 0, &orig_pixels_1[0], 0,
   1001                      &interpolate_pixels[0], 0, 1280, 1, 123);
   1002   }
   1003 }
   1004 
   1005 #define TESTTERP(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, STRIDE_B, W1280, TERP, \
   1006                  N, NEG, OFF)                                                 \
   1007   TEST_F(LibYUVPlanarTest, ARGBInterpolate##TERP##N) {                        \
   1008     const int kWidth = ((W1280) > 0) ? (W1280) : 1;                           \
   1009     const int kHeight = benchmark_height_;                                    \
   1010     const int kStrideA =                                                      \
   1011         (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;                \
   1012     const int kStrideB =                                                      \
   1013         (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;                \
   1014     align_buffer_page_end(src_argb_a, kStrideA* kHeight + OFF);               \
   1015     align_buffer_page_end(src_argb_b, kStrideA* kHeight + OFF);               \
   1016     align_buffer_page_end(dst_argb_c, kStrideB* kHeight);                     \
   1017     align_buffer_page_end(dst_argb_opt, kStrideB* kHeight);                   \
   1018     for (int i = 0; i < kStrideA * kHeight; ++i) {                            \
   1019       src_argb_a[i + OFF] = (fastrand() & 0xff);                              \
   1020       src_argb_b[i + OFF] = (fastrand() & 0xff);                              \
   1021     }                                                                         \
   1022     MaskCpuFlags(disable_cpu_flags_);                                         \
   1023     ARGBInterpolate(src_argb_a + OFF, kStrideA, src_argb_b + OFF, kStrideA,   \
   1024                     dst_argb_c, kStrideB, kWidth, NEG kHeight, TERP);         \
   1025     MaskCpuFlags(benchmark_cpu_info_);                                        \
   1026     for (int i = 0; i < benchmark_iterations_; ++i) {                         \
   1027       ARGBInterpolate(src_argb_a + OFF, kStrideA, src_argb_b + OFF, kStrideA, \
   1028                       dst_argb_opt, kStrideB, kWidth, NEG kHeight, TERP);     \
   1029     }                                                                         \
   1030     for (int i = 0; i < kStrideB * kHeight; ++i) {                            \
   1031       EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]);                              \
   1032     }                                                                         \
   1033     free_aligned_buffer_page_end(src_argb_a);                                 \
   1034     free_aligned_buffer_page_end(src_argb_b);                                 \
   1035     free_aligned_buffer_page_end(dst_argb_c);                                 \
   1036     free_aligned_buffer_page_end(dst_argb_opt);                               \
   1037   }
   1038 
   1039 #define TESTINTERPOLATE(TERP)                                                \
   1040   TESTTERP(ARGB, 4, 1, ARGB, 4, 1, benchmark_width_ - 1, TERP, _Any, +, 0)   \
   1041   TESTTERP(ARGB, 4, 1, ARGB, 4, 1, benchmark_width_, TERP, _Unaligned, +, 1) \
   1042   TESTTERP(ARGB, 4, 1, ARGB, 4, 1, benchmark_width_, TERP, _Invert, -, 0)    \
   1043   TESTTERP(ARGB, 4, 1, ARGB, 4, 1, benchmark_width_, TERP, _Opt, +, 0)
   1044 
   1045 TESTINTERPOLATE(0)
   1046 TESTINTERPOLATE(64)
   1047 TESTINTERPOLATE(128)
   1048 TESTINTERPOLATE(192)
   1049 TESTINTERPOLATE(255)
   1050 
   1051 static int TestBlend(int width,
   1052                      int height,
   1053                      int benchmark_iterations,
   1054                      int disable_cpu_flags,
   1055                      int benchmark_cpu_info,
   1056                      int invert,
   1057                      int off) {
   1058   if (width < 1) {
   1059     width = 1;
   1060   }
   1061   const int kBpp = 4;
   1062   const int kStride = width * kBpp;
   1063   align_buffer_page_end(src_argb_a, kStride * height + off);
   1064   align_buffer_page_end(src_argb_b, kStride * height + off);
   1065   align_buffer_page_end(dst_argb_c, kStride * height);
   1066   align_buffer_page_end(dst_argb_opt, kStride * height);
   1067   for (int i = 0; i < kStride * height; ++i) {
   1068     src_argb_a[i + off] = (fastrand() & 0xff);
   1069     src_argb_b[i + off] = (fastrand() & 0xff);
   1070   }
   1071   ARGBAttenuate(src_argb_a + off, kStride, src_argb_a + off, kStride, width,
   1072                 height);
   1073   ARGBAttenuate(src_argb_b + off, kStride, src_argb_b + off, kStride, width,
   1074                 height);
   1075   memset(dst_argb_c, 255, kStride * height);
   1076   memset(dst_argb_opt, 255, kStride * height);
   1077 
   1078   MaskCpuFlags(disable_cpu_flags);
   1079   ARGBBlend(src_argb_a + off, kStride, src_argb_b + off, kStride, dst_argb_c,
   1080             kStride, width, invert * height);
   1081   MaskCpuFlags(benchmark_cpu_info);
   1082   for (int i = 0; i < benchmark_iterations; ++i) {
   1083     ARGBBlend(src_argb_a + off, kStride, src_argb_b + off, kStride,
   1084               dst_argb_opt, kStride, width, invert * height);
   1085   }
   1086   int max_diff = 0;
   1087   for (int i = 0; i < kStride * height; ++i) {
   1088     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1089                        static_cast<int>(dst_argb_opt[i]));
   1090     if (abs_diff > max_diff) {
   1091       max_diff = abs_diff;
   1092     }
   1093   }
   1094   free_aligned_buffer_page_end(src_argb_a);
   1095   free_aligned_buffer_page_end(src_argb_b);
   1096   free_aligned_buffer_page_end(dst_argb_c);
   1097   free_aligned_buffer_page_end(dst_argb_opt);
   1098   return max_diff;
   1099 }
   1100 
   1101 TEST_F(LibYUVPlanarTest, ARGBBlend_Any) {
   1102   int max_diff =
   1103       TestBlend(benchmark_width_ - 4, benchmark_height_, benchmark_iterations_,
   1104                 disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1105   EXPECT_LE(max_diff, 1);
   1106 }
   1107 
   1108 TEST_F(LibYUVPlanarTest, ARGBBlend_Unaligned) {
   1109   int max_diff =
   1110       TestBlend(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1111                 disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1112   EXPECT_LE(max_diff, 1);
   1113 }
   1114 
   1115 TEST_F(LibYUVPlanarTest, ARGBBlend_Invert) {
   1116   int max_diff =
   1117       TestBlend(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1118                 disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
   1119   EXPECT_LE(max_diff, 1);
   1120 }
   1121 
   1122 TEST_F(LibYUVPlanarTest, ARGBBlend_Opt) {
   1123   int max_diff =
   1124       TestBlend(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1125                 disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1126   EXPECT_LE(max_diff, 1);
   1127 }
   1128 
   1129 static void TestBlendPlane(int width,
   1130                            int height,
   1131                            int benchmark_iterations,
   1132                            int disable_cpu_flags,
   1133                            int benchmark_cpu_info,
   1134                            int invert,
   1135                            int off) {
   1136   if (width < 1) {
   1137     width = 1;
   1138   }
   1139   const int kBpp = 1;
   1140   const int kStride = width * kBpp;
   1141   align_buffer_page_end(src_argb_a, kStride * height + off);
   1142   align_buffer_page_end(src_argb_b, kStride * height + off);
   1143   align_buffer_page_end(src_argb_alpha, kStride * height + off);
   1144   align_buffer_page_end(dst_argb_c, kStride * height + off);
   1145   align_buffer_page_end(dst_argb_opt, kStride * height + off);
   1146   memset(dst_argb_c, 255, kStride * height + off);
   1147   memset(dst_argb_opt, 255, kStride * height + off);
   1148 
   1149   // Test source is maintained exactly if alpha is 255.
   1150   for (int i = 0; i < width; ++i) {
   1151     src_argb_a[i + off] = i & 255;
   1152     src_argb_b[i + off] = 255 - (i & 255);
   1153   }
   1154   memset(src_argb_alpha + off, 255, width);
   1155   BlendPlane(src_argb_a + off, width, src_argb_b + off, width,
   1156              src_argb_alpha + off, width, dst_argb_opt + off, width, width, 1);
   1157   for (int i = 0; i < width; ++i) {
   1158     EXPECT_EQ(src_argb_a[i + off], dst_argb_opt[i + off]);
   1159   }
   1160   // Test destination is maintained exactly if alpha is 0.
   1161   memset(src_argb_alpha + off, 0, width);
   1162   BlendPlane(src_argb_a + off, width, src_argb_b + off, width,
   1163              src_argb_alpha + off, width, dst_argb_opt + off, width, width, 1);
   1164   for (int i = 0; i < width; ++i) {
   1165     EXPECT_EQ(src_argb_b[i + off], dst_argb_opt[i + off]);
   1166   }
   1167   for (int i = 0; i < kStride * height; ++i) {
   1168     src_argb_a[i + off] = (fastrand() & 0xff);
   1169     src_argb_b[i + off] = (fastrand() & 0xff);
   1170     src_argb_alpha[i + off] = (fastrand() & 0xff);
   1171   }
   1172 
   1173   MaskCpuFlags(disable_cpu_flags);
   1174   BlendPlane(src_argb_a + off, width, src_argb_b + off, width,
   1175              src_argb_alpha + off, width, dst_argb_c + off, width, width,
   1176              invert * height);
   1177   MaskCpuFlags(benchmark_cpu_info);
   1178   for (int i = 0; i < benchmark_iterations; ++i) {
   1179     BlendPlane(src_argb_a + off, width, src_argb_b + off, width,
   1180                src_argb_alpha + off, width, dst_argb_opt + off, width, width,
   1181                invert * height);
   1182   }
   1183   for (int i = 0; i < kStride * height; ++i) {
   1184     EXPECT_EQ(dst_argb_c[i + off], dst_argb_opt[i + off]);
   1185   }
   1186   free_aligned_buffer_page_end(src_argb_a);
   1187   free_aligned_buffer_page_end(src_argb_b);
   1188   free_aligned_buffer_page_end(src_argb_alpha);
   1189   free_aligned_buffer_page_end(dst_argb_c);
   1190   free_aligned_buffer_page_end(dst_argb_opt);
   1191   return;
   1192 }
   1193 
   1194 TEST_F(LibYUVPlanarTest, BlendPlane_Opt) {
   1195   TestBlendPlane(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1196                  disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1197 }
   1198 TEST_F(LibYUVPlanarTest, BlendPlane_Unaligned) {
   1199   TestBlendPlane(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1200                  disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1201 }
   1202 TEST_F(LibYUVPlanarTest, BlendPlane_Any) {
   1203   TestBlendPlane(benchmark_width_ - 4, benchmark_height_, benchmark_iterations_,
   1204                  disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1205 }
   1206 TEST_F(LibYUVPlanarTest, BlendPlane_Invert) {
   1207   TestBlendPlane(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1208                  disable_cpu_flags_, benchmark_cpu_info_, -1, 1);
   1209 }
   1210 
   1211 #define SUBSAMPLE(v, a) ((((v) + (a)-1)) / (a))
   1212 
   1213 static void TestI420Blend(int width,
   1214                           int height,
   1215                           int benchmark_iterations,
   1216                           int disable_cpu_flags,
   1217                           int benchmark_cpu_info,
   1218                           int invert,
   1219                           int off) {
   1220   width = ((width) > 0) ? (width) : 1;
   1221   const int kStrideUV = SUBSAMPLE(width, 2);
   1222   const int kSizeUV = kStrideUV * SUBSAMPLE(height, 2);
   1223   align_buffer_page_end(src_y0, width * height + off);
   1224   align_buffer_page_end(src_u0, kSizeUV + off);
   1225   align_buffer_page_end(src_v0, kSizeUV + off);
   1226   align_buffer_page_end(src_y1, width * height + off);
   1227   align_buffer_page_end(src_u1, kSizeUV + off);
   1228   align_buffer_page_end(src_v1, kSizeUV + off);
   1229   align_buffer_page_end(src_a, width * height + off);
   1230   align_buffer_page_end(dst_y_c, width * height + off);
   1231   align_buffer_page_end(dst_u_c, kSizeUV + off);
   1232   align_buffer_page_end(dst_v_c, kSizeUV + off);
   1233   align_buffer_page_end(dst_y_opt, width * height + off);
   1234   align_buffer_page_end(dst_u_opt, kSizeUV + off);
   1235   align_buffer_page_end(dst_v_opt, kSizeUV + off);
   1236 
   1237   MemRandomize(src_y0, width * height + off);
   1238   MemRandomize(src_u0, kSizeUV + off);
   1239   MemRandomize(src_v0, kSizeUV + off);
   1240   MemRandomize(src_y1, width * height + off);
   1241   MemRandomize(src_u1, kSizeUV + off);
   1242   MemRandomize(src_v1, kSizeUV + off);
   1243   MemRandomize(src_a, width * height + off);
   1244   memset(dst_y_c, 255, width * height + off);
   1245   memset(dst_u_c, 255, kSizeUV + off);
   1246   memset(dst_v_c, 255, kSizeUV + off);
   1247   memset(dst_y_opt, 255, width * height + off);
   1248   memset(dst_u_opt, 255, kSizeUV + off);
   1249   memset(dst_v_opt, 255, kSizeUV + off);
   1250 
   1251   MaskCpuFlags(disable_cpu_flags);
   1252   I420Blend(src_y0 + off, width, src_u0 + off, kStrideUV, src_v0 + off,
   1253             kStrideUV, src_y1 + off, width, src_u1 + off, kStrideUV,
   1254             src_v1 + off, kStrideUV, src_a + off, width, dst_y_c + off, width,
   1255             dst_u_c + off, kStrideUV, dst_v_c + off, kStrideUV, width,
   1256             invert * height);
   1257   MaskCpuFlags(benchmark_cpu_info);
   1258   for (int i = 0; i < benchmark_iterations; ++i) {
   1259     I420Blend(src_y0 + off, width, src_u0 + off, kStrideUV, src_v0 + off,
   1260               kStrideUV, src_y1 + off, width, src_u1 + off, kStrideUV,
   1261               src_v1 + off, kStrideUV, src_a + off, width, dst_y_opt + off,
   1262               width, dst_u_opt + off, kStrideUV, dst_v_opt + off, kStrideUV,
   1263               width, invert * height);
   1264   }
   1265   for (int i = 0; i < width * height; ++i) {
   1266     EXPECT_EQ(dst_y_c[i + off], dst_y_opt[i + off]);
   1267   }
   1268   for (int i = 0; i < kSizeUV; ++i) {
   1269     EXPECT_EQ(dst_u_c[i + off], dst_u_opt[i + off]);
   1270     EXPECT_EQ(dst_v_c[i + off], dst_v_opt[i + off]);
   1271   }
   1272   free_aligned_buffer_page_end(src_y0);
   1273   free_aligned_buffer_page_end(src_u0);
   1274   free_aligned_buffer_page_end(src_v0);
   1275   free_aligned_buffer_page_end(src_y1);
   1276   free_aligned_buffer_page_end(src_u1);
   1277   free_aligned_buffer_page_end(src_v1);
   1278   free_aligned_buffer_page_end(src_a);
   1279   free_aligned_buffer_page_end(dst_y_c);
   1280   free_aligned_buffer_page_end(dst_u_c);
   1281   free_aligned_buffer_page_end(dst_v_c);
   1282   free_aligned_buffer_page_end(dst_y_opt);
   1283   free_aligned_buffer_page_end(dst_u_opt);
   1284   free_aligned_buffer_page_end(dst_v_opt);
   1285   return;
   1286 }
   1287 
   1288 TEST_F(LibYUVPlanarTest, I420Blend_Opt) {
   1289   TestI420Blend(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1290                 disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1291 }
   1292 TEST_F(LibYUVPlanarTest, I420Blend_Unaligned) {
   1293   TestI420Blend(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1294                 disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1295 }
   1296 
   1297 // TODO(fbarchard): DISABLED because _Any uses C.  Avoid C and re-enable.
   1298 TEST_F(LibYUVPlanarTest, DISABLED_I420Blend_Any) {
   1299   TestI420Blend(benchmark_width_ - 4, benchmark_height_, benchmark_iterations_,
   1300                 disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1301 }
   1302 TEST_F(LibYUVPlanarTest, I420Blend_Invert) {
   1303   TestI420Blend(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1304                 disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
   1305 }
   1306 
   1307 TEST_F(LibYUVPlanarTest, TestAffine) {
   1308   SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]);
   1309   SIMD_ALIGNED(uint8 interpolate_pixels_C[1280][4]);
   1310 
   1311   for (int i = 0; i < 1280; ++i) {
   1312     for (int j = 0; j < 4; ++j) {
   1313       orig_pixels_0[i][j] = i;
   1314     }
   1315   }
   1316 
   1317   float uv_step[4] = {0.f, 0.f, 0.75f, 0.f};
   1318 
   1319   ARGBAffineRow_C(&orig_pixels_0[0][0], 0, &interpolate_pixels_C[0][0], uv_step,
   1320                   1280);
   1321   EXPECT_EQ(0u, interpolate_pixels_C[0][0]);
   1322   EXPECT_EQ(96u, interpolate_pixels_C[128][0]);
   1323   EXPECT_EQ(191u, interpolate_pixels_C[255][3]);
   1324 
   1325 #if defined(HAS_ARGBAFFINEROW_SSE2)
   1326   SIMD_ALIGNED(uint8 interpolate_pixels_Opt[1280][4]);
   1327   ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0],
   1328                      uv_step, 1280);
   1329   EXPECT_EQ(0, memcmp(interpolate_pixels_Opt, interpolate_pixels_C, 1280 * 4));
   1330 
   1331   int has_sse2 = TestCpuFlag(kCpuHasSSE2);
   1332   if (has_sse2) {
   1333     for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
   1334       ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0],
   1335                          uv_step, 1280);
   1336     }
   1337   }
   1338 #endif
   1339 }
   1340 
   1341 TEST_F(LibYUVPlanarTest, TestCopyPlane) {
   1342   int err = 0;
   1343   int yw = benchmark_width_;
   1344   int yh = benchmark_height_;
   1345   int b = 12;
   1346   int i, j;
   1347 
   1348   int y_plane_size = (yw + b * 2) * (yh + b * 2);
   1349   align_buffer_page_end(orig_y, y_plane_size);
   1350   align_buffer_page_end(dst_c, y_plane_size);
   1351   align_buffer_page_end(dst_opt, y_plane_size);
   1352 
   1353   memset(orig_y, 0, y_plane_size);
   1354   memset(dst_c, 0, y_plane_size);
   1355   memset(dst_opt, 0, y_plane_size);
   1356 
   1357   // Fill image buffers with random data.
   1358   for (i = b; i < (yh + b); ++i) {
   1359     for (j = b; j < (yw + b); ++j) {
   1360       orig_y[i * (yw + b * 2) + j] = fastrand() & 0xff;
   1361     }
   1362   }
   1363 
   1364   // Fill destination buffers with random data.
   1365   for (i = 0; i < y_plane_size; ++i) {
   1366     uint8 random_number = fastrand() & 0x7f;
   1367     dst_c[i] = random_number;
   1368     dst_opt[i] = dst_c[i];
   1369   }
   1370 
   1371   int y_off = b * (yw + b * 2) + b;
   1372 
   1373   int y_st = yw + b * 2;
   1374   int stride = 8;
   1375 
   1376   // Disable all optimizations.
   1377   MaskCpuFlags(disable_cpu_flags_);
   1378   for (j = 0; j < benchmark_iterations_; j++) {
   1379     CopyPlane(orig_y + y_off, y_st, dst_c + y_off, stride, yw, yh);
   1380   }
   1381 
   1382   // Enable optimizations.
   1383   MaskCpuFlags(benchmark_cpu_info_);
   1384   for (j = 0; j < benchmark_iterations_; j++) {
   1385     CopyPlane(orig_y + y_off, y_st, dst_opt + y_off, stride, yw, yh);
   1386   }
   1387 
   1388   for (i = 0; i < y_plane_size; ++i) {
   1389     if (dst_c[i] != dst_opt[i])
   1390       ++err;
   1391   }
   1392 
   1393   free_aligned_buffer_page_end(orig_y);
   1394   free_aligned_buffer_page_end(dst_c);
   1395   free_aligned_buffer_page_end(dst_opt);
   1396 
   1397   EXPECT_EQ(0, err);
   1398 }
   1399 
   1400 static int TestMultiply(int width,
   1401                         int height,
   1402                         int benchmark_iterations,
   1403                         int disable_cpu_flags,
   1404                         int benchmark_cpu_info,
   1405                         int invert,
   1406                         int off) {
   1407   if (width < 1) {
   1408     width = 1;
   1409   }
   1410   const int kBpp = 4;
   1411   const int kStride = width * kBpp;
   1412   align_buffer_page_end(src_argb_a, kStride * height + off);
   1413   align_buffer_page_end(src_argb_b, kStride * height + off);
   1414   align_buffer_page_end(dst_argb_c, kStride * height);
   1415   align_buffer_page_end(dst_argb_opt, kStride * height);
   1416   for (int i = 0; i < kStride * height; ++i) {
   1417     src_argb_a[i + off] = (fastrand() & 0xff);
   1418     src_argb_b[i + off] = (fastrand() & 0xff);
   1419   }
   1420   memset(dst_argb_c, 0, kStride * height);
   1421   memset(dst_argb_opt, 0, kStride * height);
   1422 
   1423   MaskCpuFlags(disable_cpu_flags);
   1424   ARGBMultiply(src_argb_a + off, kStride, src_argb_b + off, kStride, dst_argb_c,
   1425                kStride, width, invert * height);
   1426   MaskCpuFlags(benchmark_cpu_info);
   1427   for (int i = 0; i < benchmark_iterations; ++i) {
   1428     ARGBMultiply(src_argb_a + off, kStride, src_argb_b + off, kStride,
   1429                  dst_argb_opt, kStride, width, invert * height);
   1430   }
   1431   int max_diff = 0;
   1432   for (int i = 0; i < kStride * height; ++i) {
   1433     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1434                        static_cast<int>(dst_argb_opt[i]));
   1435     if (abs_diff > max_diff) {
   1436       max_diff = abs_diff;
   1437     }
   1438   }
   1439   free_aligned_buffer_page_end(src_argb_a);
   1440   free_aligned_buffer_page_end(src_argb_b);
   1441   free_aligned_buffer_page_end(dst_argb_c);
   1442   free_aligned_buffer_page_end(dst_argb_opt);
   1443   return max_diff;
   1444 }
   1445 
   1446 TEST_F(LibYUVPlanarTest, ARGBMultiply_Any) {
   1447   int max_diff = TestMultiply(benchmark_width_ - 1, benchmark_height_,
   1448                               benchmark_iterations_, disable_cpu_flags_,
   1449                               benchmark_cpu_info_, +1, 0);
   1450   EXPECT_LE(max_diff, 1);
   1451 }
   1452 
   1453 TEST_F(LibYUVPlanarTest, ARGBMultiply_Unaligned) {
   1454   int max_diff =
   1455       TestMultiply(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1456                    disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1457   EXPECT_LE(max_diff, 1);
   1458 }
   1459 
   1460 TEST_F(LibYUVPlanarTest, ARGBMultiply_Invert) {
   1461   int max_diff =
   1462       TestMultiply(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1463                    disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
   1464   EXPECT_LE(max_diff, 1);
   1465 }
   1466 
   1467 TEST_F(LibYUVPlanarTest, ARGBMultiply_Opt) {
   1468   int max_diff =
   1469       TestMultiply(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1470                    disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1471   EXPECT_LE(max_diff, 1);
   1472 }
   1473 
   1474 static int TestAdd(int width,
   1475                    int height,
   1476                    int benchmark_iterations,
   1477                    int disable_cpu_flags,
   1478                    int benchmark_cpu_info,
   1479                    int invert,
   1480                    int off) {
   1481   if (width < 1) {
   1482     width = 1;
   1483   }
   1484   const int kBpp = 4;
   1485   const int kStride = width * kBpp;
   1486   align_buffer_page_end(src_argb_a, kStride * height + off);
   1487   align_buffer_page_end(src_argb_b, kStride * height + off);
   1488   align_buffer_page_end(dst_argb_c, kStride * height);
   1489   align_buffer_page_end(dst_argb_opt, kStride * height);
   1490   for (int i = 0; i < kStride * height; ++i) {
   1491     src_argb_a[i + off] = (fastrand() & 0xff);
   1492     src_argb_b[i + off] = (fastrand() & 0xff);
   1493   }
   1494   memset(dst_argb_c, 0, kStride * height);
   1495   memset(dst_argb_opt, 0, kStride * height);
   1496 
   1497   MaskCpuFlags(disable_cpu_flags);
   1498   ARGBAdd(src_argb_a + off, kStride, src_argb_b + off, kStride, dst_argb_c,
   1499           kStride, width, invert * height);
   1500   MaskCpuFlags(benchmark_cpu_info);
   1501   for (int i = 0; i < benchmark_iterations; ++i) {
   1502     ARGBAdd(src_argb_a + off, kStride, src_argb_b + off, kStride, dst_argb_opt,
   1503             kStride, width, invert * height);
   1504   }
   1505   int max_diff = 0;
   1506   for (int i = 0; i < kStride * height; ++i) {
   1507     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1508                        static_cast<int>(dst_argb_opt[i]));
   1509     if (abs_diff > max_diff) {
   1510       max_diff = abs_diff;
   1511     }
   1512   }
   1513   free_aligned_buffer_page_end(src_argb_a);
   1514   free_aligned_buffer_page_end(src_argb_b);
   1515   free_aligned_buffer_page_end(dst_argb_c);
   1516   free_aligned_buffer_page_end(dst_argb_opt);
   1517   return max_diff;
   1518 }
   1519 
   1520 TEST_F(LibYUVPlanarTest, ARGBAdd_Any) {
   1521   int max_diff =
   1522       TestAdd(benchmark_width_ - 1, benchmark_height_, benchmark_iterations_,
   1523               disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1524   EXPECT_LE(max_diff, 1);
   1525 }
   1526 
   1527 TEST_F(LibYUVPlanarTest, ARGBAdd_Unaligned) {
   1528   int max_diff =
   1529       TestAdd(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1530               disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1531   EXPECT_LE(max_diff, 1);
   1532 }
   1533 
   1534 TEST_F(LibYUVPlanarTest, ARGBAdd_Invert) {
   1535   int max_diff =
   1536       TestAdd(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1537               disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
   1538   EXPECT_LE(max_diff, 1);
   1539 }
   1540 
   1541 TEST_F(LibYUVPlanarTest, ARGBAdd_Opt) {
   1542   int max_diff =
   1543       TestAdd(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1544               disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1545   EXPECT_LE(max_diff, 1);
   1546 }
   1547 
   1548 static int TestSubtract(int width,
   1549                         int height,
   1550                         int benchmark_iterations,
   1551                         int disable_cpu_flags,
   1552                         int benchmark_cpu_info,
   1553                         int invert,
   1554                         int off) {
   1555   if (width < 1) {
   1556     width = 1;
   1557   }
   1558   const int kBpp = 4;
   1559   const int kStride = width * kBpp;
   1560   align_buffer_page_end(src_argb_a, kStride * height + off);
   1561   align_buffer_page_end(src_argb_b, kStride * height + off);
   1562   align_buffer_page_end(dst_argb_c, kStride * height);
   1563   align_buffer_page_end(dst_argb_opt, kStride * height);
   1564   for (int i = 0; i < kStride * height; ++i) {
   1565     src_argb_a[i + off] = (fastrand() & 0xff);
   1566     src_argb_b[i + off] = (fastrand() & 0xff);
   1567   }
   1568   memset(dst_argb_c, 0, kStride * height);
   1569   memset(dst_argb_opt, 0, kStride * height);
   1570 
   1571   MaskCpuFlags(disable_cpu_flags);
   1572   ARGBSubtract(src_argb_a + off, kStride, src_argb_b + off, kStride, dst_argb_c,
   1573                kStride, width, invert * height);
   1574   MaskCpuFlags(benchmark_cpu_info);
   1575   for (int i = 0; i < benchmark_iterations; ++i) {
   1576     ARGBSubtract(src_argb_a + off, kStride, src_argb_b + off, kStride,
   1577                  dst_argb_opt, kStride, width, invert * height);
   1578   }
   1579   int max_diff = 0;
   1580   for (int i = 0; i < kStride * height; ++i) {
   1581     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1582                        static_cast<int>(dst_argb_opt[i]));
   1583     if (abs_diff > max_diff) {
   1584       max_diff = abs_diff;
   1585     }
   1586   }
   1587   free_aligned_buffer_page_end(src_argb_a);
   1588   free_aligned_buffer_page_end(src_argb_b);
   1589   free_aligned_buffer_page_end(dst_argb_c);
   1590   free_aligned_buffer_page_end(dst_argb_opt);
   1591   return max_diff;
   1592 }
   1593 
   1594 TEST_F(LibYUVPlanarTest, ARGBSubtract_Any) {
   1595   int max_diff = TestSubtract(benchmark_width_ - 1, benchmark_height_,
   1596                               benchmark_iterations_, disable_cpu_flags_,
   1597                               benchmark_cpu_info_, +1, 0);
   1598   EXPECT_LE(max_diff, 1);
   1599 }
   1600 
   1601 TEST_F(LibYUVPlanarTest, ARGBSubtract_Unaligned) {
   1602   int max_diff =
   1603       TestSubtract(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1604                    disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1605   EXPECT_LE(max_diff, 1);
   1606 }
   1607 
   1608 TEST_F(LibYUVPlanarTest, ARGBSubtract_Invert) {
   1609   int max_diff =
   1610       TestSubtract(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1611                    disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
   1612   EXPECT_LE(max_diff, 1);
   1613 }
   1614 
   1615 TEST_F(LibYUVPlanarTest, ARGBSubtract_Opt) {
   1616   int max_diff =
   1617       TestSubtract(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1618                    disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1619   EXPECT_LE(max_diff, 1);
   1620 }
   1621 
   1622 static int TestSobel(int width,
   1623                      int height,
   1624                      int benchmark_iterations,
   1625                      int disable_cpu_flags,
   1626                      int benchmark_cpu_info,
   1627                      int invert,
   1628                      int off) {
   1629   if (width < 1) {
   1630     width = 1;
   1631   }
   1632   const int kBpp = 4;
   1633   const int kStride = width * kBpp;
   1634   align_buffer_page_end(src_argb_a, kStride * height + off);
   1635   align_buffer_page_end(dst_argb_c, kStride * height);
   1636   align_buffer_page_end(dst_argb_opt, kStride * height);
   1637   memset(src_argb_a, 0, kStride * height + off);
   1638   for (int i = 0; i < kStride * height; ++i) {
   1639     src_argb_a[i + off] = (fastrand() & 0xff);
   1640   }
   1641   memset(dst_argb_c, 0, kStride * height);
   1642   memset(dst_argb_opt, 0, kStride * height);
   1643 
   1644   MaskCpuFlags(disable_cpu_flags);
   1645   ARGBSobel(src_argb_a + off, kStride, dst_argb_c, kStride, width,
   1646             invert * height);
   1647   MaskCpuFlags(benchmark_cpu_info);
   1648   for (int i = 0; i < benchmark_iterations; ++i) {
   1649     ARGBSobel(src_argb_a + off, kStride, dst_argb_opt, kStride, width,
   1650               invert * height);
   1651   }
   1652   int max_diff = 0;
   1653   for (int i = 0; i < kStride * height; ++i) {
   1654     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1655                        static_cast<int>(dst_argb_opt[i]));
   1656     if (abs_diff > max_diff) {
   1657       max_diff = abs_diff;
   1658     }
   1659   }
   1660   free_aligned_buffer_page_end(src_argb_a);
   1661   free_aligned_buffer_page_end(dst_argb_c);
   1662   free_aligned_buffer_page_end(dst_argb_opt);
   1663   return max_diff;
   1664 }
   1665 
   1666 TEST_F(LibYUVPlanarTest, ARGBSobel_Any) {
   1667   int max_diff =
   1668       TestSobel(benchmark_width_ - 1, benchmark_height_, benchmark_iterations_,
   1669                 disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1670   EXPECT_EQ(0, max_diff);
   1671 }
   1672 
   1673 TEST_F(LibYUVPlanarTest, ARGBSobel_Unaligned) {
   1674   int max_diff =
   1675       TestSobel(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1676                 disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1677   EXPECT_EQ(0, max_diff);
   1678 }
   1679 
   1680 TEST_F(LibYUVPlanarTest, ARGBSobel_Invert) {
   1681   int max_diff =
   1682       TestSobel(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1683                 disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
   1684   EXPECT_EQ(0, max_diff);
   1685 }
   1686 
   1687 TEST_F(LibYUVPlanarTest, ARGBSobel_Opt) {
   1688   int max_diff =
   1689       TestSobel(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1690                 disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1691   EXPECT_EQ(0, max_diff);
   1692 }
   1693 
   1694 static int TestSobelToPlane(int width,
   1695                             int height,
   1696                             int benchmark_iterations,
   1697                             int disable_cpu_flags,
   1698                             int benchmark_cpu_info,
   1699                             int invert,
   1700                             int off) {
   1701   if (width < 1) {
   1702     width = 1;
   1703   }
   1704   const int kSrcBpp = 4;
   1705   const int kDstBpp = 1;
   1706   const int kSrcStride = (width * kSrcBpp + 15) & ~15;
   1707   const int kDstStride = (width * kDstBpp + 15) & ~15;
   1708   align_buffer_page_end(src_argb_a, kSrcStride * height + off);
   1709   align_buffer_page_end(dst_argb_c, kDstStride * height);
   1710   align_buffer_page_end(dst_argb_opt, kDstStride * height);
   1711   memset(src_argb_a, 0, kSrcStride * height + off);
   1712   for (int i = 0; i < kSrcStride * height; ++i) {
   1713     src_argb_a[i + off] = (fastrand() & 0xff);
   1714   }
   1715   memset(dst_argb_c, 0, kDstStride * height);
   1716   memset(dst_argb_opt, 0, kDstStride * height);
   1717 
   1718   MaskCpuFlags(disable_cpu_flags);
   1719   ARGBSobelToPlane(src_argb_a + off, kSrcStride, dst_argb_c, kDstStride, width,
   1720                    invert * height);
   1721   MaskCpuFlags(benchmark_cpu_info);
   1722   for (int i = 0; i < benchmark_iterations; ++i) {
   1723     ARGBSobelToPlane(src_argb_a + off, kSrcStride, dst_argb_opt, kDstStride,
   1724                      width, invert * height);
   1725   }
   1726   int max_diff = 0;
   1727   for (int i = 0; i < kDstStride * height; ++i) {
   1728     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1729                        static_cast<int>(dst_argb_opt[i]));
   1730     if (abs_diff > max_diff) {
   1731       max_diff = abs_diff;
   1732     }
   1733   }
   1734   free_aligned_buffer_page_end(src_argb_a);
   1735   free_aligned_buffer_page_end(dst_argb_c);
   1736   free_aligned_buffer_page_end(dst_argb_opt);
   1737   return max_diff;
   1738 }
   1739 
   1740 TEST_F(LibYUVPlanarTest, ARGBSobelToPlane_Any) {
   1741   int max_diff = TestSobelToPlane(benchmark_width_ - 1, benchmark_height_,
   1742                                   benchmark_iterations_, disable_cpu_flags_,
   1743                                   benchmark_cpu_info_, +1, 0);
   1744   EXPECT_EQ(0, max_diff);
   1745 }
   1746 
   1747 TEST_F(LibYUVPlanarTest, ARGBSobelToPlane_Unaligned) {
   1748   int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_,
   1749                                   benchmark_iterations_, disable_cpu_flags_,
   1750                                   benchmark_cpu_info_, +1, 1);
   1751   EXPECT_EQ(0, max_diff);
   1752 }
   1753 
   1754 TEST_F(LibYUVPlanarTest, ARGBSobelToPlane_Invert) {
   1755   int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_,
   1756                                   benchmark_iterations_, disable_cpu_flags_,
   1757                                   benchmark_cpu_info_, -1, 0);
   1758   EXPECT_EQ(0, max_diff);
   1759 }
   1760 
   1761 TEST_F(LibYUVPlanarTest, ARGBSobelToPlane_Opt) {
   1762   int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_,
   1763                                   benchmark_iterations_, disable_cpu_flags_,
   1764                                   benchmark_cpu_info_, +1, 0);
   1765   EXPECT_EQ(0, max_diff);
   1766 }
   1767 
   1768 static int TestSobelXY(int width,
   1769                        int height,
   1770                        int benchmark_iterations,
   1771                        int disable_cpu_flags,
   1772                        int benchmark_cpu_info,
   1773                        int invert,
   1774                        int off) {
   1775   if (width < 1) {
   1776     width = 1;
   1777   }
   1778   const int kBpp = 4;
   1779   const int kStride = width * kBpp;
   1780   align_buffer_page_end(src_argb_a, kStride * height + off);
   1781   align_buffer_page_end(dst_argb_c, kStride * height);
   1782   align_buffer_page_end(dst_argb_opt, kStride * height);
   1783   memset(src_argb_a, 0, kStride * height + off);
   1784   for (int i = 0; i < kStride * height; ++i) {
   1785     src_argb_a[i + off] = (fastrand() & 0xff);
   1786   }
   1787   memset(dst_argb_c, 0, kStride * height);
   1788   memset(dst_argb_opt, 0, kStride * height);
   1789 
   1790   MaskCpuFlags(disable_cpu_flags);
   1791   ARGBSobelXY(src_argb_a + off, kStride, dst_argb_c, kStride, width,
   1792               invert * height);
   1793   MaskCpuFlags(benchmark_cpu_info);
   1794   for (int i = 0; i < benchmark_iterations; ++i) {
   1795     ARGBSobelXY(src_argb_a + off, kStride, dst_argb_opt, kStride, width,
   1796                 invert * height);
   1797   }
   1798   int max_diff = 0;
   1799   for (int i = 0; i < kStride * height; ++i) {
   1800     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1801                        static_cast<int>(dst_argb_opt[i]));
   1802     if (abs_diff > max_diff) {
   1803       max_diff = abs_diff;
   1804     }
   1805   }
   1806   free_aligned_buffer_page_end(src_argb_a);
   1807   free_aligned_buffer_page_end(dst_argb_c);
   1808   free_aligned_buffer_page_end(dst_argb_opt);
   1809   return max_diff;
   1810 }
   1811 
   1812 TEST_F(LibYUVPlanarTest, ARGBSobelXY_Any) {
   1813   int max_diff = TestSobelXY(benchmark_width_ - 1, benchmark_height_,
   1814                              benchmark_iterations_, disable_cpu_flags_,
   1815                              benchmark_cpu_info_, +1, 0);
   1816   EXPECT_EQ(0, max_diff);
   1817 }
   1818 
   1819 TEST_F(LibYUVPlanarTest, ARGBSobelXY_Unaligned) {
   1820   int max_diff =
   1821       TestSobelXY(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1822                   disable_cpu_flags_, benchmark_cpu_info_, +1, 1);
   1823   EXPECT_EQ(0, max_diff);
   1824 }
   1825 
   1826 TEST_F(LibYUVPlanarTest, ARGBSobelXY_Invert) {
   1827   int max_diff =
   1828       TestSobelXY(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1829                   disable_cpu_flags_, benchmark_cpu_info_, -1, 0);
   1830   EXPECT_EQ(0, max_diff);
   1831 }
   1832 
   1833 TEST_F(LibYUVPlanarTest, ARGBSobelXY_Opt) {
   1834   int max_diff =
   1835       TestSobelXY(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1836                   disable_cpu_flags_, benchmark_cpu_info_, +1, 0);
   1837   EXPECT_EQ(0, max_diff);
   1838 }
   1839 
   1840 static int TestBlur(int width,
   1841                     int height,
   1842                     int benchmark_iterations,
   1843                     int disable_cpu_flags,
   1844                     int benchmark_cpu_info,
   1845                     int invert,
   1846                     int off,
   1847                     int radius) {
   1848   if (width < 1) {
   1849     width = 1;
   1850   }
   1851   const int kBpp = 4;
   1852   const int kStride = width * kBpp;
   1853   align_buffer_page_end(src_argb_a, kStride * height + off);
   1854   align_buffer_page_end(dst_cumsum, width * height * 16);
   1855   align_buffer_page_end(dst_argb_c, kStride * height);
   1856   align_buffer_page_end(dst_argb_opt, kStride * height);
   1857   for (int i = 0; i < kStride * height; ++i) {
   1858     src_argb_a[i + off] = (fastrand() & 0xff);
   1859   }
   1860   memset(dst_cumsum, 0, width * height * 16);
   1861   memset(dst_argb_c, 0, kStride * height);
   1862   memset(dst_argb_opt, 0, kStride * height);
   1863 
   1864   MaskCpuFlags(disable_cpu_flags);
   1865   ARGBBlur(src_argb_a + off, kStride, dst_argb_c, kStride,
   1866            reinterpret_cast<int32*>(dst_cumsum), width * 4, width,
   1867            invert * height, radius);
   1868   MaskCpuFlags(benchmark_cpu_info);
   1869   for (int i = 0; i < benchmark_iterations; ++i) {
   1870     ARGBBlur(src_argb_a + off, kStride, dst_argb_opt, kStride,
   1871              reinterpret_cast<int32*>(dst_cumsum), width * 4, width,
   1872              invert * height, radius);
   1873   }
   1874   int max_diff = 0;
   1875   for (int i = 0; i < kStride * height; ++i) {
   1876     int abs_diff = abs(static_cast<int>(dst_argb_c[i]) -
   1877                        static_cast<int>(dst_argb_opt[i]));
   1878     if (abs_diff > max_diff) {
   1879       max_diff = abs_diff;
   1880     }
   1881   }
   1882   free_aligned_buffer_page_end(src_argb_a);
   1883   free_aligned_buffer_page_end(dst_cumsum);
   1884   free_aligned_buffer_page_end(dst_argb_c);
   1885   free_aligned_buffer_page_end(dst_argb_opt);
   1886   return max_diff;
   1887 }
   1888 
   1889 static const int kBlurSize = 55;
   1890 TEST_F(LibYUVPlanarTest, ARGBBlur_Any) {
   1891   int max_diff =
   1892       TestBlur(benchmark_width_ - 1, benchmark_height_, benchmark_iterations_,
   1893                disable_cpu_flags_, benchmark_cpu_info_, +1, 0, kBlurSize);
   1894   EXPECT_LE(max_diff, 1);
   1895 }
   1896 
   1897 TEST_F(LibYUVPlanarTest, ARGBBlur_Unaligned) {
   1898   int max_diff =
   1899       TestBlur(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1900                disable_cpu_flags_, benchmark_cpu_info_, +1, 1, kBlurSize);
   1901   EXPECT_LE(max_diff, 1);
   1902 }
   1903 
   1904 TEST_F(LibYUVPlanarTest, ARGBBlur_Invert) {
   1905   int max_diff =
   1906       TestBlur(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1907                disable_cpu_flags_, benchmark_cpu_info_, -1, 0, kBlurSize);
   1908   EXPECT_LE(max_diff, 1);
   1909 }
   1910 
   1911 TEST_F(LibYUVPlanarTest, ARGBBlur_Opt) {
   1912   int max_diff =
   1913       TestBlur(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1914                disable_cpu_flags_, benchmark_cpu_info_, +1, 0, kBlurSize);
   1915   EXPECT_LE(max_diff, 1);
   1916 }
   1917 
   1918 static const int kBlurSmallSize = 5;
   1919 TEST_F(LibYUVPlanarTest, ARGBBlurSmall_Any) {
   1920   int max_diff =
   1921       TestBlur(benchmark_width_ - 1, benchmark_height_, benchmark_iterations_,
   1922                disable_cpu_flags_, benchmark_cpu_info_, +1, 0, kBlurSmallSize);
   1923   EXPECT_LE(max_diff, 1);
   1924 }
   1925 
   1926 TEST_F(LibYUVPlanarTest, ARGBBlurSmall_Unaligned) {
   1927   int max_diff =
   1928       TestBlur(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1929                disable_cpu_flags_, benchmark_cpu_info_, +1, 1, kBlurSmallSize);
   1930   EXPECT_LE(max_diff, 1);
   1931 }
   1932 
   1933 TEST_F(LibYUVPlanarTest, ARGBBlurSmall_Invert) {
   1934   int max_diff =
   1935       TestBlur(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1936                disable_cpu_flags_, benchmark_cpu_info_, -1, 0, kBlurSmallSize);
   1937   EXPECT_LE(max_diff, 1);
   1938 }
   1939 
   1940 TEST_F(LibYUVPlanarTest, ARGBBlurSmall_Opt) {
   1941   int max_diff =
   1942       TestBlur(benchmark_width_, benchmark_height_, benchmark_iterations_,
   1943                disable_cpu_flags_, benchmark_cpu_info_, +1, 0, kBlurSmallSize);
   1944   EXPECT_LE(max_diff, 1);
   1945 }
   1946 
   1947 TEST_F(LibYUVPlanarTest, TestARGBPolynomial) {
   1948   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   1949   SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]);
   1950   SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]);
   1951   memset(orig_pixels, 0, sizeof(orig_pixels));
   1952 
   1953   SIMD_ALIGNED(static const float kWarmifyPolynomial[16]) = {
   1954       0.94230f,  -3.03300f,    -2.92500f,    0.f,  // C0
   1955       0.584500f, 1.112000f,    1.535000f,    1.f,  // C1 x
   1956       0.001313f, -0.002503f,   -0.004496f,   0.f,  // C2 x * x
   1957       0.0f,      0.000006965f, 0.000008781f, 0.f,  // C3 x * x * x
   1958   };
   1959 
   1960   // Test blue
   1961   orig_pixels[0][0] = 255u;
   1962   orig_pixels[0][1] = 0u;
   1963   orig_pixels[0][2] = 0u;
   1964   orig_pixels[0][3] = 128u;
   1965   // Test green
   1966   orig_pixels[1][0] = 0u;
   1967   orig_pixels[1][1] = 255u;
   1968   orig_pixels[1][2] = 0u;
   1969   orig_pixels[1][3] = 0u;
   1970   // Test red
   1971   orig_pixels[2][0] = 0u;
   1972   orig_pixels[2][1] = 0u;
   1973   orig_pixels[2][2] = 255u;
   1974   orig_pixels[2][3] = 255u;
   1975   // Test white
   1976   orig_pixels[3][0] = 255u;
   1977   orig_pixels[3][1] = 255u;
   1978   orig_pixels[3][2] = 255u;
   1979   orig_pixels[3][3] = 255u;
   1980   // Test color
   1981   orig_pixels[4][0] = 16u;
   1982   orig_pixels[4][1] = 64u;
   1983   orig_pixels[4][2] = 192u;
   1984   orig_pixels[4][3] = 224u;
   1985   // Do 16 to test asm version.
   1986   ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0,
   1987                  &kWarmifyPolynomial[0], 16, 1);
   1988   EXPECT_EQ(235u, dst_pixels_opt[0][0]);
   1989   EXPECT_EQ(0u, dst_pixels_opt[0][1]);
   1990   EXPECT_EQ(0u, dst_pixels_opt[0][2]);
   1991   EXPECT_EQ(128u, dst_pixels_opt[0][3]);
   1992   EXPECT_EQ(0u, dst_pixels_opt[1][0]);
   1993   EXPECT_EQ(233u, dst_pixels_opt[1][1]);
   1994   EXPECT_EQ(0u, dst_pixels_opt[1][2]);
   1995   EXPECT_EQ(0u, dst_pixels_opt[1][3]);
   1996   EXPECT_EQ(0u, dst_pixels_opt[2][0]);
   1997   EXPECT_EQ(0u, dst_pixels_opt[2][1]);
   1998   EXPECT_EQ(241u, dst_pixels_opt[2][2]);
   1999   EXPECT_EQ(255u, dst_pixels_opt[2][3]);
   2000   EXPECT_EQ(235u, dst_pixels_opt[3][0]);
   2001   EXPECT_EQ(233u, dst_pixels_opt[3][1]);
   2002   EXPECT_EQ(241u, dst_pixels_opt[3][2]);
   2003   EXPECT_EQ(255u, dst_pixels_opt[3][3]);
   2004   EXPECT_EQ(10u, dst_pixels_opt[4][0]);
   2005   EXPECT_EQ(59u, dst_pixels_opt[4][1]);
   2006   EXPECT_EQ(188u, dst_pixels_opt[4][2]);
   2007   EXPECT_EQ(224u, dst_pixels_opt[4][3]);
   2008 
   2009   for (int i = 0; i < 1280; ++i) {
   2010     orig_pixels[i][0] = i;
   2011     orig_pixels[i][1] = i / 2;
   2012     orig_pixels[i][2] = i / 3;
   2013     orig_pixels[i][3] = i;
   2014   }
   2015 
   2016   MaskCpuFlags(disable_cpu_flags_);
   2017   ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0,
   2018                  &kWarmifyPolynomial[0], 1280, 1);
   2019   MaskCpuFlags(benchmark_cpu_info_);
   2020 
   2021   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
   2022     ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0,
   2023                    &kWarmifyPolynomial[0], 1280, 1);
   2024   }
   2025 
   2026   for (int i = 0; i < 1280; ++i) {
   2027     EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]);
   2028     EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]);
   2029     EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]);
   2030     EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]);
   2031   }
   2032 }
   2033 
   2034 int TestHalfFloatPlane(int benchmark_width,
   2035                        int benchmark_height,
   2036                        int benchmark_iterations,
   2037                        int disable_cpu_flags,
   2038                        int benchmark_cpu_info,
   2039                        float scale,
   2040                        int mask) {
   2041   int i, j;
   2042   const int y_plane_size = benchmark_width * benchmark_height * 2;
   2043 
   2044   align_buffer_page_end(orig_y, y_plane_size * 3);
   2045   uint8* dst_opt = orig_y + y_plane_size;
   2046   uint8* dst_c = orig_y + y_plane_size * 2;
   2047 
   2048   MemRandomize(orig_y, y_plane_size);
   2049   memset(dst_c, 0, y_plane_size);
   2050   memset(dst_opt, 1, y_plane_size);
   2051 
   2052   for (i = 0; i < y_plane_size / 2; ++i) {
   2053     reinterpret_cast<uint16*>(orig_y)[i] &= mask;
   2054   }
   2055 
   2056   // Disable all optimizations.
   2057   MaskCpuFlags(disable_cpu_flags);
   2058   for (j = 0; j < benchmark_iterations; j++) {
   2059     HalfFloatPlane(reinterpret_cast<uint16*>(orig_y), benchmark_width * 2,
   2060                    reinterpret_cast<uint16*>(dst_c), benchmark_width * 2, scale,
   2061                    benchmark_width, benchmark_height);
   2062   }
   2063 
   2064   // Enable optimizations.
   2065   MaskCpuFlags(benchmark_cpu_info);
   2066   for (j = 0; j < benchmark_iterations; j++) {
   2067     HalfFloatPlane(reinterpret_cast<uint16*>(orig_y), benchmark_width * 2,
   2068                    reinterpret_cast<uint16*>(dst_opt), benchmark_width * 2,
   2069                    scale, benchmark_width, benchmark_height);
   2070   }
   2071 
   2072   int max_diff = 0;
   2073   for (i = 0; i < y_plane_size / 2; ++i) {
   2074     int abs_diff = abs(static_cast<int>(reinterpret_cast<uint16*>(dst_c)[i]) -
   2075                        static_cast<int>(reinterpret_cast<uint16*>(dst_opt)[i]));
   2076     if (abs_diff > max_diff) {
   2077       max_diff = abs_diff;
   2078     }
   2079   }
   2080 
   2081   free_aligned_buffer_page_end(orig_y);
   2082   return max_diff;
   2083 }
   2084 
   2085 #if defined(__arm__)
   2086 static void EnableFlushDenormalToZero(void) {
   2087   uint32_t cw;
   2088   __asm__ __volatile__(
   2089       "vmrs   %0, fpscr         \n"
   2090       "orr    %0, %0, #0x1000000        \n"
   2091       "vmsr   fpscr, %0         \n"
   2092       : "=r"(cw)::"memory");
   2093 }
   2094 #endif
   2095 
   2096 // 5 bit exponent with bias of 15 will underflow to a denormal if scale causes
   2097 // exponent to be less than 0.  15 - log2(65536) = -1/  This shouldnt normally
   2098 // happen since scale is 1/(1<<bits) where bits is 9, 10 or 12.
   2099 
   2100 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_16bit_denormal) {
   2101 // 32 bit arm rounding on denormal case is off by 1 compared to C.
   2102 #if defined(__arm__)
   2103   EnableFlushDenormalToZero();
   2104 #endif
   2105   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2106                                 benchmark_iterations_, disable_cpu_flags_,
   2107                                 benchmark_cpu_info_, 1.0f / 65536.0f, 65535);
   2108   EXPECT_EQ(0, diff);
   2109 }
   2110 
   2111 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_16bit_One) {
   2112   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2113                                 benchmark_iterations_, disable_cpu_flags_,
   2114                                 benchmark_cpu_info_, 1.0f, 65535);
   2115   EXPECT_LE(diff, 1);
   2116 }
   2117 
   2118 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_16bit_Opt) {
   2119   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2120                                 benchmark_iterations_, disable_cpu_flags_,
   2121                                 benchmark_cpu_info_, 1.0f / 4096.0f, 65535);
   2122   EXPECT_EQ(0, diff);
   2123 }
   2124 
   2125 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_10bit_Opt) {
   2126   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2127                                 benchmark_iterations_, disable_cpu_flags_,
   2128                                 benchmark_cpu_info_, 1.0f / 1024.0f, 1023);
   2129   EXPECT_EQ(0, diff);
   2130 }
   2131 
   2132 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_9bit_Opt) {
   2133   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2134                                 benchmark_iterations_, disable_cpu_flags_,
   2135                                 benchmark_cpu_info_, 1.0f / 512.0f, 511);
   2136   EXPECT_EQ(0, diff);
   2137 }
   2138 
   2139 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_Opt) {
   2140   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2141                                 benchmark_iterations_, disable_cpu_flags_,
   2142                                 benchmark_cpu_info_, 1.0f / 4096.0f, 4095);
   2143   EXPECT_EQ(0, diff);
   2144 }
   2145 
   2146 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_Offby1) {
   2147   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2148                                 benchmark_iterations_, disable_cpu_flags_,
   2149                                 benchmark_cpu_info_, 1.0f / 4095.0f, 4095);
   2150   EXPECT_EQ(0, diff);
   2151 }
   2152 
   2153 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_One) {
   2154   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2155                                 benchmark_iterations_, disable_cpu_flags_,
   2156                                 benchmark_cpu_info_, 1.0f, 2047);
   2157   EXPECT_EQ(0, diff);
   2158 }
   2159 
   2160 TEST_F(LibYUVPlanarTest, TestHalfFloatPlane_12bit_One) {
   2161   int diff = TestHalfFloatPlane(benchmark_width_, benchmark_height_,
   2162                                 benchmark_iterations_, disable_cpu_flags_,
   2163                                 benchmark_cpu_info_, 1.0f, 4095);
   2164   EXPECT_LE(diff, 1);
   2165 }
   2166 
   2167 TEST_F(LibYUVPlanarTest, TestARGBLumaColorTable) {
   2168   SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
   2169   SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]);
   2170   SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]);
   2171   memset(orig_pixels, 0, sizeof(orig_pixels));
   2172 
   2173   align_buffer_page_end(lumacolortable, 32768);
   2174   int v = 0;
   2175   for (int i = 0; i < 32768; ++i) {
   2176     lumacolortable[i] = v;
   2177     v += 3;
   2178   }
   2179   // Test blue
   2180   orig_pixels[0][0] = 255u;
   2181   orig_pixels[0][1] = 0u;
   2182   orig_pixels[0][2] = 0u;
   2183   orig_pixels[0][3] = 128u;
   2184   // Test green
   2185   orig_pixels[1][0] = 0u;
   2186   orig_pixels[1][1] = 255u;
   2187   orig_pixels[1][2] = 0u;
   2188   orig_pixels[1][3] = 0u;
   2189   // Test red
   2190   orig_pixels[2][0] = 0u;
   2191   orig_pixels[2][1] = 0u;
   2192   orig_pixels[2][2] = 255u;
   2193   orig_pixels[2][3] = 255u;
   2194   // Test color
   2195   orig_pixels[3][0] = 16u;
   2196   orig_pixels[3][1] = 64u;
   2197   orig_pixels[3][2] = 192u;
   2198   orig_pixels[3][3] = 224u;
   2199   // Do 16 to test asm version.
   2200   ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0,
   2201                      &lumacolortable[0], 16, 1);
   2202   EXPECT_EQ(253u, dst_pixels_opt[0][0]);
   2203   EXPECT_EQ(0u, dst_pixels_opt[0][1]);
   2204   EXPECT_EQ(0u, dst_pixels_opt[0][2]);
   2205   EXPECT_EQ(128u, dst_pixels_opt[0][3]);
   2206   EXPECT_EQ(0u, dst_pixels_opt[1][0]);
   2207   EXPECT_EQ(253u, dst_pixels_opt[1][1]);
   2208   EXPECT_EQ(0u, dst_pixels_opt[1][2]);
   2209   EXPECT_EQ(0u, dst_pixels_opt[1][3]);
   2210   EXPECT_EQ(0u, dst_pixels_opt[2][0]);
   2211   EXPECT_EQ(0u, dst_pixels_opt[2][1]);
   2212   EXPECT_EQ(253u, dst_pixels_opt[2][2]);
   2213   EXPECT_EQ(255u, dst_pixels_opt[2][3]);
   2214   EXPECT_EQ(48u, dst_pixels_opt[3][0]);
   2215   EXPECT_EQ(192u, dst_pixels_opt[3][1]);
   2216   EXPECT_EQ(64u, dst_pixels_opt[3][2]);
   2217   EXPECT_EQ(224u, dst_pixels_opt[3][3]);
   2218 
   2219   for (int i = 0; i < 1280; ++i) {
   2220     orig_pixels[i][0] = i;
   2221     orig_pixels[i][1] = i / 2;
   2222     orig_pixels[i][2] = i / 3;
   2223     orig_pixels[i][3] = i;
   2224   }
   2225 
   2226   MaskCpuFlags(disable_cpu_flags_);
   2227   ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0,
   2228                      lumacolortable, 1280, 1);
   2229   MaskCpuFlags(benchmark_cpu_info_);
   2230 
   2231   for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
   2232     ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0,
   2233                        lumacolortable, 1280, 1);
   2234   }
   2235   for (int i = 0; i < 1280; ++i) {
   2236     EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]);
   2237     EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]);
   2238     EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]);
   2239     EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]);
   2240   }
   2241 
   2242   free_aligned_buffer_page_end(lumacolortable);
   2243 }
   2244 
   2245 TEST_F(LibYUVPlanarTest, TestARGBCopyAlpha) {
   2246   const int kSize = benchmark_width_ * benchmark_height_ * 4;
   2247   align_buffer_page_end(orig_pixels, kSize);
   2248   align_buffer_page_end(dst_pixels_opt, kSize);
   2249   align_buffer_page_end(dst_pixels_c, kSize);
   2250 
   2251   MemRandomize(orig_pixels, kSize);
   2252   MemRandomize(dst_pixels_opt, kSize);
   2253   memcpy(dst_pixels_c, dst_pixels_opt, kSize);
   2254 
   2255   MaskCpuFlags(disable_cpu_flags_);
   2256   ARGBCopyAlpha(orig_pixels, benchmark_width_ * 4, dst_pixels_c,
   2257                 benchmark_width_ * 4, benchmark_width_, benchmark_height_);
   2258   MaskCpuFlags(benchmark_cpu_info_);
   2259 
   2260   for (int i = 0; i < benchmark_iterations_; ++i) {
   2261     ARGBCopyAlpha(orig_pixels, benchmark_width_ * 4, dst_pixels_opt,
   2262                   benchmark_width_ * 4, benchmark_width_, benchmark_height_);
   2263   }
   2264   for (int i = 0; i < kSize; ++i) {
   2265     EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
   2266   }
   2267 
   2268   free_aligned_buffer_page_end(dst_pixels_c);
   2269   free_aligned_buffer_page_end(dst_pixels_opt);
   2270   free_aligned_buffer_page_end(orig_pixels);
   2271 }
   2272 
   2273 TEST_F(LibYUVPlanarTest, TestARGBExtractAlpha) {
   2274   const int kPixels = benchmark_width_ * benchmark_height_;
   2275   align_buffer_page_end(src_pixels, kPixels * 4);
   2276   align_buffer_page_end(dst_pixels_opt, kPixels);
   2277   align_buffer_page_end(dst_pixels_c, kPixels);
   2278 
   2279   MemRandomize(src_pixels, kPixels * 4);
   2280   MemRandomize(dst_pixels_opt, kPixels);
   2281   memcpy(dst_pixels_c, dst_pixels_opt, kPixels);
   2282 
   2283   MaskCpuFlags(disable_cpu_flags_);
   2284   ARGBExtractAlpha(src_pixels, benchmark_width_ * 4, dst_pixels_c,
   2285                    benchmark_width_, benchmark_width_, benchmark_height_);
   2286   MaskCpuFlags(benchmark_cpu_info_);
   2287 
   2288   for (int i = 0; i < benchmark_iterations_; ++i) {
   2289     ARGBExtractAlpha(src_pixels, benchmark_width_ * 4, dst_pixels_opt,
   2290                      benchmark_width_, benchmark_width_, benchmark_height_);
   2291   }
   2292   for (int i = 0; i < kPixels; ++i) {
   2293     EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
   2294   }
   2295 
   2296   free_aligned_buffer_page_end(dst_pixels_c);
   2297   free_aligned_buffer_page_end(dst_pixels_opt);
   2298   free_aligned_buffer_page_end(src_pixels);
   2299 }
   2300 
   2301 TEST_F(LibYUVPlanarTest, TestARGBCopyYToAlpha) {
   2302   const int kPixels = benchmark_width_ * benchmark_height_;
   2303   align_buffer_page_end(orig_pixels, kPixels);
   2304   align_buffer_page_end(dst_pixels_opt, kPixels * 4);
   2305   align_buffer_page_end(dst_pixels_c, kPixels * 4);
   2306 
   2307   MemRandomize(orig_pixels, kPixels);
   2308   MemRandomize(dst_pixels_opt, kPixels * 4);
   2309   memcpy(dst_pixels_c, dst_pixels_opt, kPixels * 4);
   2310 
   2311   MaskCpuFlags(disable_cpu_flags_);
   2312   ARGBCopyYToAlpha(orig_pixels, benchmark_width_, dst_pixels_c,
   2313                    benchmark_width_ * 4, benchmark_width_, benchmark_height_);
   2314   MaskCpuFlags(benchmark_cpu_info_);
   2315 
   2316   for (int i = 0; i < benchmark_iterations_; ++i) {
   2317     ARGBCopyYToAlpha(orig_pixels, benchmark_width_, dst_pixels_opt,
   2318                      benchmark_width_ * 4, benchmark_width_, benchmark_height_);
   2319   }
   2320   for (int i = 0; i < kPixels * 4; ++i) {
   2321     EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
   2322   }
   2323 
   2324   free_aligned_buffer_page_end(dst_pixels_c);
   2325   free_aligned_buffer_page_end(dst_pixels_opt);
   2326   free_aligned_buffer_page_end(orig_pixels);
   2327 }
   2328 
   2329 static int TestARGBRect(int width,
   2330                         int height,
   2331                         int benchmark_iterations,
   2332                         int disable_cpu_flags,
   2333                         int benchmark_cpu_info,
   2334                         int invert,
   2335                         int off,
   2336                         int bpp) {
   2337   if (width < 1) {
   2338     width = 1;
   2339   }
   2340   const int kStride = width * bpp;
   2341   const int kSize = kStride * height;
   2342   const uint32 v32 = fastrand() & (bpp == 4 ? 0xffffffff : 0xff);
   2343 
   2344   align_buffer_page_end(dst_argb_c, kSize + off);
   2345   align_buffer_page_end(dst_argb_opt, kSize + off);
   2346 
   2347   MemRandomize(dst_argb_c + off, kSize);
   2348   memcpy(dst_argb_opt + off, dst_argb_c + off, kSize);
   2349 
   2350   MaskCpuFlags(disable_cpu_flags);
   2351   if (bpp == 4) {
   2352     ARGBRect(dst_argb_c + off, kStride, 0, 0, width, invert * height, v32);
   2353   } else {
   2354     SetPlane(dst_argb_c + off, kStride, width, invert * height, v32);
   2355   }
   2356 
   2357   MaskCpuFlags(benchmark_cpu_info);
   2358   for (int i = 0; i < benchmark_iterations; ++i) {
   2359     if (bpp == 4) {
   2360       ARGBRect(dst_argb_opt + off, kStride, 0, 0, width, invert * height, v32);
   2361     } else {
   2362       SetPlane(dst_argb_opt + off, kStride, width, invert * height, v32);
   2363     }
   2364   }
   2365   int max_diff = 0;
   2366   for (int i = 0; i < kStride * height; ++i) {
   2367     int abs_diff = abs(static_cast<int>(dst_argb_c[i + off]) -
   2368                        static_cast<int>(dst_argb_opt[i + off]));
   2369     if (abs_diff > max_diff) {
   2370       max_diff = abs_diff;
   2371     }
   2372   }
   2373   free_aligned_buffer_page_end(dst_argb_c);
   2374   free_aligned_buffer_page_end(dst_argb_opt);
   2375   return max_diff;
   2376 }
   2377 
   2378 TEST_F(LibYUVPlanarTest, ARGBRect_Any) {
   2379   int max_diff = TestARGBRect(benchmark_width_ - 1, benchmark_height_,
   2380                               benchmark_iterations_, disable_cpu_flags_,
   2381                               benchmark_cpu_info_, +1, 0, 4);
   2382   EXPECT_EQ(0, max_diff);
   2383 }
   2384 
   2385 TEST_F(LibYUVPlanarTest, ARGBRect_Unaligned) {
   2386   int max_diff =
   2387       TestARGBRect(benchmark_width_, benchmark_height_, benchmark_iterations_,
   2388                    disable_cpu_flags_, benchmark_cpu_info_, +1, 1, 4);
   2389   EXPECT_EQ(0, max_diff);
   2390 }
   2391 
   2392 TEST_F(LibYUVPlanarTest, ARGBRect_Invert) {
   2393   int max_diff =
   2394       TestARGBRect(benchmark_width_, benchmark_height_, benchmark_iterations_,
   2395                    disable_cpu_flags_, benchmark_cpu_info_, -1, 0, 4);
   2396   EXPECT_EQ(0, max_diff);
   2397 }
   2398 
   2399 TEST_F(LibYUVPlanarTest, ARGBRect_Opt) {
   2400   int max_diff =
   2401       TestARGBRect(benchmark_width_, benchmark_height_, benchmark_iterations_,
   2402                    disable_cpu_flags_, benchmark_cpu_info_, +1, 0, 4);
   2403   EXPECT_EQ(0, max_diff);
   2404 }
   2405 
   2406 TEST_F(LibYUVPlanarTest, SetPlane_Any) {
   2407   int max_diff = TestARGBRect(benchmark_width_ - 1, benchmark_height_,
   2408                               benchmark_iterations_, disable_cpu_flags_,
   2409                               benchmark_cpu_info_, +1, 0, 1);
   2410   EXPECT_EQ(0, max_diff);
   2411 }
   2412 
   2413 TEST_F(LibYUVPlanarTest, SetPlane_Unaligned) {
   2414   int max_diff =
   2415       TestARGBRect(benchmark_width_, benchmark_height_, benchmark_iterations_,
   2416                    disable_cpu_flags_, benchmark_cpu_info_, +1, 1, 1);
   2417   EXPECT_EQ(0, max_diff);
   2418 }
   2419 
   2420 TEST_F(LibYUVPlanarTest, SetPlane_Invert) {
   2421   int max_diff =
   2422       TestARGBRect(benchmark_width_, benchmark_height_, benchmark_iterations_,
   2423                    disable_cpu_flags_, benchmark_cpu_info_, -1, 0, 1);
   2424   EXPECT_EQ(0, max_diff);
   2425 }
   2426 
   2427 TEST_F(LibYUVPlanarTest, SetPlane_Opt) {
   2428   int max_diff =
   2429       TestARGBRect(benchmark_width_, benchmark_height_, benchmark_iterations_,
   2430                    disable_cpu_flags_, benchmark_cpu_info_, +1, 0, 1);
   2431   EXPECT_EQ(0, max_diff);
   2432 }
   2433 
   2434 TEST_F(LibYUVPlanarTest, MergeUVPlane_Opt) {
   2435   const int kPixels = benchmark_width_ * benchmark_height_;
   2436   align_buffer_page_end(src_pixels, kPixels * 2);
   2437   align_buffer_page_end(tmp_pixels_u, kPixels);
   2438   align_buffer_page_end(tmp_pixels_v, kPixels);
   2439   align_buffer_page_end(dst_pixels_opt, kPixels * 2);
   2440   align_buffer_page_end(dst_pixels_c, kPixels * 2);
   2441 
   2442   MemRandomize(src_pixels, kPixels * 2);
   2443   MemRandomize(tmp_pixels_u, kPixels);
   2444   MemRandomize(tmp_pixels_v, kPixels);
   2445   MemRandomize(dst_pixels_opt, kPixels * 2);
   2446   MemRandomize(dst_pixels_c, kPixels * 2);
   2447 
   2448   MaskCpuFlags(disable_cpu_flags_);
   2449   SplitUVPlane(src_pixels, benchmark_width_ * 2, tmp_pixels_u, benchmark_width_,
   2450                tmp_pixels_v, benchmark_width_, benchmark_width_,
   2451                benchmark_height_);
   2452   MergeUVPlane(tmp_pixels_u, benchmark_width_, tmp_pixels_v, benchmark_width_,
   2453                dst_pixels_c, benchmark_width_ * 2, benchmark_width_,
   2454                benchmark_height_);
   2455   MaskCpuFlags(benchmark_cpu_info_);
   2456 
   2457   SplitUVPlane(src_pixels, benchmark_width_ * 2, tmp_pixels_u, benchmark_width_,
   2458                tmp_pixels_v, benchmark_width_, benchmark_width_,
   2459                benchmark_height_);
   2460 
   2461   for (int i = 0; i < benchmark_iterations_; ++i) {
   2462     MergeUVPlane(tmp_pixels_u, benchmark_width_, tmp_pixels_v, benchmark_width_,
   2463                  dst_pixels_opt, benchmark_width_ * 2, benchmark_width_,
   2464                  benchmark_height_);
   2465   }
   2466 
   2467   for (int i = 0; i < kPixels * 2; ++i) {
   2468     EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
   2469   }
   2470 
   2471   free_aligned_buffer_page_end(src_pixels);
   2472   free_aligned_buffer_page_end(tmp_pixels_u);
   2473   free_aligned_buffer_page_end(tmp_pixels_v);
   2474   free_aligned_buffer_page_end(dst_pixels_opt);
   2475   free_aligned_buffer_page_end(dst_pixels_c);
   2476 }
   2477 
   2478 TEST_F(LibYUVPlanarTest, SplitUVPlane_Opt) {
   2479   const int kPixels = benchmark_width_ * benchmark_height_;
   2480   align_buffer_page_end(src_pixels, kPixels * 2);
   2481   align_buffer_page_end(tmp_pixels_u, kPixels);
   2482   align_buffer_page_end(tmp_pixels_v, kPixels);
   2483   align_buffer_page_end(dst_pixels_opt, kPixels * 2);
   2484   align_buffer_page_end(dst_pixels_c, kPixels * 2);
   2485 
   2486   MemRandomize(src_pixels, kPixels * 2);
   2487   MemRandomize(tmp_pixels_u, kPixels);
   2488   MemRandomize(tmp_pixels_v, kPixels);
   2489   MemRandomize(dst_pixels_opt, kPixels * 2);
   2490   MemRandomize(dst_pixels_c, kPixels * 2);
   2491 
   2492   MaskCpuFlags(disable_cpu_flags_);
   2493   SplitUVPlane(src_pixels, benchmark_width_ * 2, tmp_pixels_u, benchmark_width_,
   2494                tmp_pixels_v, benchmark_width_, benchmark_width_,
   2495                benchmark_height_);
   2496   MergeUVPlane(tmp_pixels_u, benchmark_width_, tmp_pixels_v, benchmark_width_,
   2497                dst_pixels_c, benchmark_width_ * 2, benchmark_width_,
   2498                benchmark_height_);
   2499   MaskCpuFlags(benchmark_cpu_info_);
   2500 
   2501   for (int i = 0; i < benchmark_iterations_; ++i) {
   2502     SplitUVPlane(src_pixels, benchmark_width_ * 2, tmp_pixels_u,
   2503                  benchmark_width_, tmp_pixels_v, benchmark_width_,
   2504                  benchmark_width_, benchmark_height_);
   2505   }
   2506   MergeUVPlane(tmp_pixels_u, benchmark_width_, tmp_pixels_v, benchmark_width_,
   2507                dst_pixels_opt, benchmark_width_ * 2, benchmark_width_,
   2508                benchmark_height_);
   2509 
   2510   for (int i = 0; i < kPixels * 2; ++i) {
   2511     EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
   2512   }
   2513 
   2514   free_aligned_buffer_page_end(src_pixels);
   2515   free_aligned_buffer_page_end(tmp_pixels_u);
   2516   free_aligned_buffer_page_end(tmp_pixels_v);
   2517   free_aligned_buffer_page_end(dst_pixels_opt);
   2518   free_aligned_buffer_page_end(dst_pixels_c);
   2519 }
   2520 
   2521 }  // namespace libyuv
   2522