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