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