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