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/convert_argb.h"
15#include "libyuv/convert_from.h"
16#include "libyuv/compare.h"
17#include "libyuv/cpu_id.h"
18#include "libyuv/format_conversion.h"
19#include "libyuv/planar_functions.h"
20#include "libyuv/rotate.h"
21#include "../unit_test/unit_test.h"
22
23#if defined(_MSC_VER)
24#define SIMD_ALIGNED(var) __declspec(align(16)) var
25#else  // __GNUC__
26#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
27#endif
28
29namespace libyuv {
30
31#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, N, NEG) \
32TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N##_OptVsC) {                        \
33  const int kWidth = 1280;                                                     \
34  const int kHeight = 720;                                                     \
35  const int kStride = (kWidth * 8 * BPP_B + 7) / 8;                            \
36  align_buffer_16(src_y, kWidth * kHeight);                                    \
37  align_buffer_16(src_u, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y);            \
38  align_buffer_16(src_v, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y);            \
39  align_buffer_16(dst_argb_c, kStride * kHeight);                              \
40  align_buffer_16(dst_argb_opt, kStride * kHeight);                            \
41  srandom(time(NULL));                                                         \
42  for (int i = 0; i < kHeight; ++i)                                            \
43    for (int j = 0; j < kWidth; ++j)                                           \
44      src_y[(i * kWidth) + j] = (random() & 0xff);                             \
45  for (int i = 0; i < kHeight / SUBSAMP_Y; ++i)                                \
46    for (int j = 0; j < kWidth / SUBSAMP_X; ++j) {                             \
47      src_u[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff);                 \
48      src_v[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff);                 \
49    }                                                                          \
50  MaskCpuFlags(kCpuInitialized);                                               \
51  FMT_PLANAR##To##FMT_B(src_y, kWidth,                                         \
52                        src_u, kWidth / SUBSAMP_X,                             \
53                        src_v, kWidth / SUBSAMP_X,                             \
54                        dst_argb_c, kStride,                                   \
55                        kWidth, NEG kHeight);                                  \
56  MaskCpuFlags(-1);                                                            \
57  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
58    FMT_PLANAR##To##FMT_B(src_y, kWidth,                                       \
59                          src_u, kWidth / SUBSAMP_X,                           \
60                          src_v, kWidth / SUBSAMP_X,                           \
61                          dst_argb_opt, kStride,                               \
62                          kWidth, NEG kHeight);                                \
63  }                                                                            \
64  int max_diff = 0;                                                            \
65  for (int i = 0; i < kHeight; ++i) {                                          \
66    for (int j = 0; j < kWidth * BPP_B; ++j) {                                 \
67      int abs_diff =                                                           \
68          abs(static_cast<int>(dst_argb_c[i * kWidth * BPP_B + j]) -           \
69              static_cast<int>(dst_argb_opt[i * kWidth * BPP_B + j]));         \
70      if (abs_diff > max_diff) {                                               \
71        max_diff = abs_diff;                                                   \
72      }                                                                        \
73    }                                                                          \
74  }                                                                            \
75  EXPECT_LE(max_diff, 2);                                                      \
76  free_aligned_buffer_16(src_y)                                                \
77  free_aligned_buffer_16(src_u)                                                \
78  free_aligned_buffer_16(src_v)                                                \
79  free_aligned_buffer_16(dst_argb_c)                                           \
80  free_aligned_buffer_16(dst_argb_opt)                                         \
81}
82
83#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B)          \
84    TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, , +)        \
85    TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, Invert, -)
86
87TESTPLANARTOB(I420, 2, 2, ARGB, 4)
88TESTPLANARTOB(I420, 2, 2, BGRA, 4)
89TESTPLANARTOB(I420, 2, 2, ABGR, 4)
90TESTPLANARTOB(I420, 2, 2, RGBA, 4)
91TESTPLANARTOB(I420, 2, 2, RAW, 3)
92TESTPLANARTOB(I420, 2, 2, RGB24, 3)
93TESTPLANARTOB(I420, 2, 2, RGB565, 2)
94TESTPLANARTOB(I420, 2, 2, ARGB1555, 2)
95TESTPLANARTOB(I420, 2, 2, ARGB4444, 2)
96TESTPLANARTOB(I422, 2, 1, ARGB, 4)
97TESTPLANARTOB(I422, 2, 1, BGRA, 4)
98TESTPLANARTOB(I422, 2, 1, ABGR, 4)
99TESTPLANARTOB(I422, 2, 1, RGBA, 4)
100TESTPLANARTOB(I411, 4, 1, ARGB, 4)
101TESTPLANARTOB(I444, 1, 1, ARGB, 4)
102TESTPLANARTOB(I420, 2, 2, YUY2, 2)
103TESTPLANARTOB(I420, 2, 2, UYVY, 2)
104// TODO(fbarchard): Re-enable test and fix valgrind.
105// TESTPLANARTOB(I420, 2, 2, V210, 16 / 6)
106TESTPLANARTOB(I420, 2, 2, I400, 1)
107TESTPLANARTOB(I420, 2, 2, BayerBGGR, 1)
108TESTPLANARTOB(I420, 2, 2, BayerRGGB, 1)
109TESTPLANARTOB(I420, 2, 2, BayerGBRG, 1)
110TESTPLANARTOB(I420, 2, 2, BayerGRBG, 1)
111
112#define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,       \
113                         N, NEG)                                               \
114TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N##_OptVsC) {                        \
115  const int kWidth = 1280;                                                     \
116  const int kHeight = 720;                                                     \
117  align_buffer_16(src_y, kWidth * kHeight);                                    \
118  align_buffer_16(src_uv, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y * 2);       \
119  align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight);                     \
120  align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight);                   \
121  srandom(time(NULL));                                                         \
122  for (int i = 0; i < kHeight; ++i)                                            \
123    for (int j = 0; j < kWidth; ++j)                                           \
124      src_y[(i * kWidth) + j] = (random() & 0xff);                             \
125  for (int i = 0; i < kHeight / SUBSAMP_Y; ++i)                                \
126    for (int j = 0; j < kWidth / SUBSAMP_X * 2; ++j) {                         \
127      src_uv[(i * kWidth / SUBSAMP_X) * 2 + j] = (random() & 0xff);            \
128    }                                                                          \
129  MaskCpuFlags(kCpuInitialized);                                               \
130  FMT_PLANAR##To##FMT_B(src_y, kWidth,                                         \
131                        src_uv, kWidth / SUBSAMP_X * 2,                        \
132                        dst_argb_c, kWidth * BPP_B,                            \
133                        kWidth, NEG kHeight);                                  \
134  MaskCpuFlags(-1);                                                            \
135  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
136    FMT_PLANAR##To##FMT_B(src_y, kWidth,                                       \
137                          src_uv, kWidth / SUBSAMP_X * 2,                      \
138                          dst_argb_opt, kWidth * BPP_B,                        \
139                          kWidth, NEG kHeight);                                \
140  }                                                                            \
141  int max_diff = 0;                                                            \
142  for (int i = 0; i < kHeight; ++i) {                                          \
143    for (int j = 0; j < kWidth * BPP_B; ++j) {                                 \
144      int abs_diff =                                                           \
145        abs(static_cast<int>(dst_argb_c[i * kWidth * BPP_B + j]) -             \
146            static_cast<int>(dst_argb_opt[i * kWidth * BPP_B + j]));           \
147      if (abs_diff > max_diff) {                                               \
148        max_diff = abs_diff;                                                   \
149      }                                                                        \
150    }                                                                          \
151  }                                                                            \
152  EXPECT_LE(max_diff, 3);                                                      \
153  free_aligned_buffer_16(src_y)                                                \
154  free_aligned_buffer_16(src_uv)                                               \
155  free_aligned_buffer_16(dst_argb_c)                                           \
156  free_aligned_buffer_16(dst_argb_opt)                                         \
157}
158
159#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B)        \
160    TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, , +)      \
161    TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, Invert, -)
162
163TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4)
164TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4)
165TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2)
166TESTBIPLANARTOB(NV21, 2, 2, RGB565, 2)
167
168#define TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, N, NEG) \
169TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N##_OptVsC) {                        \
170  const int kWidth = 1280;                                                     \
171  const int kHeight = 720;                                                     \
172  const int kStride = (kWidth * 8 * BPP_A + 7) / 8;                            \
173  align_buffer_16(src_argb, kStride * kHeight);                                \
174  align_buffer_16(dst_y_c, kWidth * kHeight);                                  \
175  align_buffer_16(dst_u_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y);          \
176  align_buffer_16(dst_v_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y);          \
177  align_buffer_16(dst_y_opt, kWidth * kHeight);                                \
178  align_buffer_16(dst_u_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y);        \
179  align_buffer_16(dst_v_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y);        \
180  srandom(time(NULL));                                                         \
181  for (int i = 0; i < kHeight; ++i)                                            \
182    for (int j = 0; j < kStride; ++j)                                          \
183      src_argb[(i * kStride) + j] = (random() & 0xff);                         \
184  MaskCpuFlags(kCpuInitialized);                                               \
185  FMT_A##To##FMT_PLANAR(src_argb, kStride,                                     \
186                        dst_y_c, kWidth,                                       \
187                        dst_u_c, kWidth / SUBSAMP_X,                           \
188                        dst_v_c, kWidth / SUBSAMP_X,                           \
189                        kWidth, NEG kHeight);                                  \
190  MaskCpuFlags(-1);                                                            \
191  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
192    FMT_A##To##FMT_PLANAR(src_argb, kStride,                                   \
193                          dst_y_opt, kWidth,                                   \
194                          dst_u_opt, kWidth / SUBSAMP_X,                       \
195                          dst_v_opt, kWidth / SUBSAMP_X,                       \
196                          kWidth, NEG kHeight);                                \
197  }                                                                            \
198  int max_diff = 0;                                                            \
199  for (int i = 0; i < kHeight; ++i) {                                          \
200    for (int j = 0; j < kWidth; ++j) {                                         \
201      int abs_diff =                                                           \
202          abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
203              static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
204      if (abs_diff > max_diff) {                                               \
205        max_diff = abs_diff;                                                   \
206      }                                                                        \
207    }                                                                          \
208  }                                                                            \
209  EXPECT_LE(max_diff, 2);                                                      \
210  for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) {                              \
211    for (int j = 0; j < kWidth / SUBSAMP_X; ++j) {                             \
212      int abs_diff =                                                           \
213          abs(static_cast<int>(dst_u_c[i * kWidth / SUBSAMP_X + j]) -          \
214              static_cast<int>(dst_u_opt[i * kWidth / SUBSAMP_X + j]));        \
215      if (abs_diff > max_diff) {                                               \
216        max_diff = abs_diff;                                                   \
217      }                                                                        \
218    }                                                                          \
219  }                                                                            \
220  EXPECT_LE(max_diff, 2);                                                      \
221  for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) {                              \
222    for (int j = 0; j < kWidth / SUBSAMP_X; ++j) {                             \
223      int abs_diff =                                                           \
224          abs(static_cast<int>(dst_v_c[i * kWidth / SUBSAMP_X + j]) -          \
225              static_cast<int>(dst_v_opt[i * kWidth / SUBSAMP_X + j]));        \
226      if (abs_diff > max_diff) {                                               \
227        max_diff = abs_diff;                                                   \
228      }                                                                        \
229    }                                                                          \
230  }                                                                            \
231  EXPECT_LE(max_diff, 2);                                                      \
232  free_aligned_buffer_16(dst_y_c)                                              \
233  free_aligned_buffer_16(dst_u_c)                                              \
234  free_aligned_buffer_16(dst_v_c)                                              \
235  free_aligned_buffer_16(dst_y_opt)                                            \
236  free_aligned_buffer_16(dst_u_opt)                                            \
237  free_aligned_buffer_16(dst_v_opt)                                            \
238  free_aligned_buffer_16(src_argb)                                             \
239}
240
241#define TESTATOPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)          \
242    TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, , +)        \
243    TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, Invert, -)
244
245TESTATOPLANAR(ARGB, 4, I420, 2, 2)
246TESTATOPLANAR(BGRA, 4, I420, 2, 2)
247TESTATOPLANAR(ABGR, 4, I420, 2, 2)
248TESTATOPLANAR(RGBA, 4, I420, 2, 2)
249TESTATOPLANAR(RAW, 3, I420, 2, 2)
250TESTATOPLANAR(RGB24, 3, I420, 2, 2)
251TESTATOPLANAR(RGB565, 2, I420, 2, 2)
252TESTATOPLANAR(ARGB1555, 2, I420, 2, 2)
253TESTATOPLANAR(ARGB4444, 2, I420, 2, 2)
254// TESTATOPLANAR(ARGB, 4, I411, 4, 1)
255TESTATOPLANAR(ARGB, 4, I422, 2, 1)
256// TESTATOPLANAR(ARGB, 4, I444, 1, 1)
257// TODO(fbarchard): Implement and test 411 and 444
258TESTATOPLANAR(YUY2, 2, I420, 2, 2)
259TESTATOPLANAR(UYVY, 2, I420, 2, 2)
260TESTATOPLANAR(YUY2, 2, I422, 2, 1)
261TESTATOPLANAR(UYVY, 2, I422, 2, 1)
262TESTATOPLANAR(V210, 16 / 6, I420, 2, 2)
263TESTATOPLANAR(I400, 1, I420, 2, 2)
264TESTATOPLANAR(BayerBGGR, 1, I420, 2, 2)
265TESTATOPLANAR(BayerRGGB, 1, I420, 2, 2)
266TESTATOPLANAR(BayerGBRG, 1, I420, 2, 2)
267TESTATOPLANAR(BayerGRBG, 1, I420, 2, 2)
268
269#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, N, NEG)                \
270TEST_F(libyuvTest, FMT_A##To##FMT_B##N##_OptVsC) {                             \
271  const int kWidth = 1280;                                                     \
272  const int kHeight = 720;                                                     \
273  align_buffer_16(src_argb, (kWidth * BPP_A) * kHeight);                       \
274  align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight);                     \
275  align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight);                   \
276  srandom(time(NULL));                                                         \
277  for (int i = 0; i < kHeight * kWidth * BPP_A; ++i) {                         \
278    src_argb[i] = (random() & 0xff);                                           \
279  }                                                                            \
280  MaskCpuFlags(kCpuInitialized);                                               \
281  FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A,                                \
282                   dst_argb_c, kWidth * BPP_B,                                 \
283                   kWidth, NEG kHeight);                                       \
284  MaskCpuFlags(-1);                                                            \
285  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
286    FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A,                              \
287                     dst_argb_opt, kWidth * BPP_B,                             \
288                     kWidth, NEG kHeight);                                     \
289  }                                                                            \
290  int max_diff = 0;                                                            \
291  for (int i = 0; i < kHeight * kWidth * BPP_B; ++i) {                         \
292    int abs_diff =                                                             \
293        abs(static_cast<int>(dst_argb_c[i]) -                                  \
294            static_cast<int>(dst_argb_opt[i]));                                \
295    if (abs_diff > max_diff) {                                                 \
296      max_diff = abs_diff;                                                     \
297    }                                                                          \
298  }                                                                            \
299  EXPECT_LE(max_diff, 2);                                                      \
300  free_aligned_buffer_16(src_argb)                                             \
301  free_aligned_buffer_16(dst_argb_c)                                           \
302  free_aligned_buffer_16(dst_argb_opt)                                         \
303}
304#define TESTATOB(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B)                         \
305    TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, , +)                       \
306    TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, Invert, -)
307
308TESTATOB(I400, 1, 1, I400, 1)
309TESTATOB(ARGB, 4, 4, ARGB, 4)
310TESTATOB(ARGB, 4, 4, BGRA, 4)
311TESTATOB(ARGB, 4, 4, ABGR, 4)
312TESTATOB(ARGB, 4, 4, RGBA, 4)
313TESTATOB(ARGB, 4, 4, RAW, 3)
314TESTATOB(ARGB, 4, 4, RGB24, 3)
315TESTATOB(ARGB, 4, 4, RGB565, 2)
316TESTATOB(ARGB, 4, 4, ARGB1555, 2)
317TESTATOB(ARGB, 4, 4, ARGB4444, 2)
318TESTATOB(BGRA, 4, 4, ARGB, 4)
319TESTATOB(ABGR, 4, 4, ARGB, 4)
320TESTATOB(RGBA, 4, 4, ARGB, 4)
321TESTATOB(RAW, 3, 3, ARGB, 4)
322TESTATOB(RGB24, 3, 3, ARGB, 4)
323TESTATOB(RGB565, 2, 2, ARGB, 4)
324TESTATOB(ARGB1555, 2, 2, ARGB, 4)
325TESTATOB(ARGB4444, 2, 2, ARGB, 4)
326TESTATOB(YUY2, 2, 2, ARGB, 4)
327TESTATOB(UYVY, 2, 2, ARGB, 4)
328TESTATOB(M420, 3 / 2, 1, ARGB, 4)
329
330static const int kReadPad = 16;  // Allow overread of 16 bytes.
331#define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B)                   \
332TEST_F(libyuvTest, FMT_A##To##FMT_B##_Random) {                                \
333  srandom(time(NULL));                                                         \
334  for (int times = 0; times < benchmark_iterations_; ++times) {                \
335    const int kWidth = (random() & 63) + 1;                                    \
336    const int kHeight = (random() & 31) + 1;                                   \
337    align_buffer_page_end(src_argb, (kWidth * BPP_A) * kHeight + kReadPad);    \
338    align_buffer_page_end(dst_argb_c, (kWidth * BPP_B) * kHeight);             \
339    align_buffer_page_end(dst_argb_opt, (kWidth * BPP_B) * kHeight);           \
340    for (int i = 0; i < kHeight * kWidth * BPP_A; ++i) {                       \
341      src_argb[i] = (random() & 0xff);                                         \
342    }                                                                          \
343    MaskCpuFlags(kCpuInitialized);                                             \
344    FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A,                              \
345                     dst_argb_c, kWidth * BPP_B,                               \
346                     kWidth, kHeight);                                         \
347    MaskCpuFlags(-1);                                                          \
348    FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A,                              \
349                     dst_argb_opt, kWidth * BPP_B,                             \
350                     kWidth, kHeight);                                         \
351    int max_diff = 0;                                                          \
352    for (int i = 0; i < kHeight * kWidth * BPP_B; ++i) {                       \
353      int abs_diff =                                                           \
354          abs(static_cast<int>(dst_argb_c[i]) -                                \
355              static_cast<int>(dst_argb_opt[i]));                              \
356      if (abs_diff > max_diff) {                                               \
357        max_diff = abs_diff;                                                   \
358      }                                                                        \
359    }                                                                          \
360    EXPECT_LE(max_diff, 2);                                                    \
361    free_aligned_buffer_page_end(src_argb)                                     \
362    free_aligned_buffer_page_end(dst_argb_c)                                   \
363    free_aligned_buffer_page_end(dst_argb_opt)                                 \
364  }                                                                            \
365}
366
367TESTATOBRANDOM(ARGB, 4, 4, ARGB, 4)
368TESTATOBRANDOM(ARGB, 4, 4, BGRA, 4)
369TESTATOBRANDOM(ARGB, 4, 4, ABGR, 4)
370TESTATOBRANDOM(ARGB, 4, 4, RGBA, 4)
371TESTATOBRANDOM(ARGB, 4, 4, RAW, 3)
372TESTATOBRANDOM(ARGB, 4, 4, RGB24, 3)
373TESTATOBRANDOM(ARGB, 4, 4, RGB565, 2)
374TESTATOBRANDOM(ARGB, 4, 4, ARGB1555, 2)
375TESTATOBRANDOM(ARGB, 4, 4, ARGB4444, 2)
376
377TESTATOBRANDOM(BGRA, 4, 4, ARGB, 4)
378TESTATOBRANDOM(ABGR, 4, 4, ARGB, 4)
379TESTATOBRANDOM(RGBA, 4, 4, ARGB, 4)
380TESTATOBRANDOM(RAW, 3, 3, ARGB, 4)
381TESTATOBRANDOM(RGB24, 3, 3, ARGB, 4)
382TESTATOBRANDOM(RGB565, 2, 2, ARGB, 4)
383TESTATOBRANDOM(ARGB1555, 2, 2, ARGB, 4)
384TESTATOBRANDOM(ARGB4444, 2, 2, ARGB, 4)
385
386TEST_F(libyuvTest, TestAttenuate) {
387  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
388  SIMD_ALIGNED(uint8 atten_pixels[256][4]);
389  SIMD_ALIGNED(uint8 unatten_pixels[256][4]);
390  SIMD_ALIGNED(uint8 atten2_pixels[256][4]);
391
392  // Test unattenuation clamps
393  orig_pixels[0][0] = 200u;
394  orig_pixels[0][1] = 129u;
395  orig_pixels[0][2] = 127u;
396  orig_pixels[0][3] = 128u;
397  // Test unattenuation transparent and opaque are unaffected
398  orig_pixels[1][0] = 16u;
399  orig_pixels[1][1] = 64u;
400  orig_pixels[1][2] = 192u;
401  orig_pixels[1][3] = 0u;
402  orig_pixels[2][0] = 16u;
403  orig_pixels[2][1] = 64u;
404  orig_pixels[2][2] = 192u;
405  orig_pixels[2][3] = 255u;
406  orig_pixels[3][0] = 16u;
407  orig_pixels[3][1] = 64u;
408  orig_pixels[3][2] = 192u;
409  orig_pixels[3][3] = 128u;
410  ARGBUnattenuate(&orig_pixels[0][0], 0, &unatten_pixels[0][0], 0, 4, 1);
411  EXPECT_EQ(255u, unatten_pixels[0][0]);
412  EXPECT_EQ(255u, unatten_pixels[0][1]);
413  EXPECT_EQ(254u, unatten_pixels[0][2]);
414  EXPECT_EQ(128u, unatten_pixels[0][3]);
415  EXPECT_EQ(16u, unatten_pixels[1][0]);
416  EXPECT_EQ(64u, unatten_pixels[1][1]);
417  EXPECT_EQ(192u, unatten_pixels[1][2]);
418  EXPECT_EQ(0u, unatten_pixels[1][3]);
419  EXPECT_EQ(16u, unatten_pixels[2][0]);
420  EXPECT_EQ(64u, unatten_pixels[2][1]);
421  EXPECT_EQ(192u, unatten_pixels[2][2]);
422  EXPECT_EQ(255u, unatten_pixels[2][3]);
423  EXPECT_EQ(32u, unatten_pixels[3][0]);
424  EXPECT_EQ(128u, unatten_pixels[3][1]);
425  EXPECT_EQ(255u, unatten_pixels[3][2]);
426  EXPECT_EQ(128u, unatten_pixels[3][3]);
427
428  for (int i = 0; i < 256; ++i) {
429    orig_pixels[i][0] = i;
430    orig_pixels[i][1] = i / 2;
431    orig_pixels[i][2] = i / 3;
432    orig_pixels[i][3] = i;
433  }
434  ARGBAttenuate(&orig_pixels[0][0], 0, &atten_pixels[0][0], 0, 256, 1);
435  ARGBUnattenuate(&atten_pixels[0][0], 0, &unatten_pixels[0][0], 0, 256, 1);
436  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
437    ARGBAttenuate(&unatten_pixels[0][0], 0, &atten2_pixels[0][0], 0, 256, 1);
438  }
439  for (int i = 0; i < 256; ++i) {
440    EXPECT_NEAR(atten_pixels[i][0], atten2_pixels[i][0], 2);
441    EXPECT_NEAR(atten_pixels[i][1], atten2_pixels[i][1], 2);
442    EXPECT_NEAR(atten_pixels[i][2], atten2_pixels[i][2], 2);
443    EXPECT_NEAR(atten_pixels[i][3], atten2_pixels[i][3], 2);
444  }
445  // Make sure transparent, 50% and opaque are fully accurate.
446  EXPECT_EQ(0, atten_pixels[0][0]);
447  EXPECT_EQ(0, atten_pixels[0][1]);
448  EXPECT_EQ(0, atten_pixels[0][2]);
449  EXPECT_EQ(0, atten_pixels[0][3]);
450  EXPECT_EQ(64, atten_pixels[128][0]);
451  EXPECT_EQ(32, atten_pixels[128][1]);
452  EXPECT_EQ(21,  atten_pixels[128][2]);
453  EXPECT_EQ(128, atten_pixels[128][3]);
454  EXPECT_EQ(255, atten_pixels[255][0]);
455  EXPECT_EQ(127, atten_pixels[255][1]);
456  EXPECT_EQ(85,  atten_pixels[255][2]);
457  EXPECT_EQ(255, atten_pixels[255][3]);
458}
459
460TEST_F(libyuvTest, TestARGBComputeCumulativeSum) {
461  SIMD_ALIGNED(uint8 orig_pixels[16][16][4]);
462  SIMD_ALIGNED(int32 added_pixels[16][16][4]);
463
464  for (int y = 0; y < 16; ++y) {
465    for (int x = 0; x < 16; ++x) {
466      orig_pixels[y][x][0] = 1u;
467      orig_pixels[y][x][1] = 2u;
468      orig_pixels[y][x][2] = 3u;
469      orig_pixels[y][x][3] = 255u;
470    }
471  }
472
473  ARGBComputeCumulativeSum(&orig_pixels[0][0][0], 16 * 4,
474                           &added_pixels[0][0][0], 16 * 4,
475                           16, 16);
476
477  for (int y = 0; y < 16; ++y) {
478    for (int x = 0; x < 16; ++x) {
479      EXPECT_EQ((x + 1) * (y + 1), added_pixels[y][x][0]);
480      EXPECT_EQ((x + 1) * (y + 1) * 2, added_pixels[y][x][1]);
481      EXPECT_EQ((x + 1) * (y + 1) * 3, added_pixels[y][x][2]);
482      EXPECT_EQ((x + 1) * (y + 1) * 255, added_pixels[y][x][3]);
483    }
484  }
485}
486
487TEST_F(libyuvTest, TestARGBGray) {
488  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
489
490  // Test blue
491  orig_pixels[0][0] = 255u;
492  orig_pixels[0][1] = 0u;
493  orig_pixels[0][2] = 0u;
494  orig_pixels[0][3] = 128u;
495  // Test green
496  orig_pixels[1][0] = 0u;
497  orig_pixels[1][1] = 255u;
498  orig_pixels[1][2] = 0u;
499  orig_pixels[1][3] = 0u;
500  // Test red
501  orig_pixels[2][0] = 0u;
502  orig_pixels[2][1] = 0u;
503  orig_pixels[2][2] = 255u;
504  orig_pixels[2][3] = 255u;
505  // Test color
506  orig_pixels[3][0] = 16u;
507  orig_pixels[3][1] = 64u;
508  orig_pixels[3][2] = 192u;
509  orig_pixels[3][3] = 224u;
510  // Do 16 to test asm version.
511  ARGBGray(&orig_pixels[0][0], 0, 0, 0, 16, 1);
512  EXPECT_EQ(27u, orig_pixels[0][0]);
513  EXPECT_EQ(27u, orig_pixels[0][1]);
514  EXPECT_EQ(27u, orig_pixels[0][2]);
515  EXPECT_EQ(128u, orig_pixels[0][3]);
516  EXPECT_EQ(151u, orig_pixels[1][0]);
517  EXPECT_EQ(151u, orig_pixels[1][1]);
518  EXPECT_EQ(151u, orig_pixels[1][2]);
519  EXPECT_EQ(0u, orig_pixels[1][3]);
520  EXPECT_EQ(75u, orig_pixels[2][0]);
521  EXPECT_EQ(75u, orig_pixels[2][1]);
522  EXPECT_EQ(75u, orig_pixels[2][2]);
523  EXPECT_EQ(255u, orig_pixels[2][3]);
524  EXPECT_EQ(96u, orig_pixels[3][0]);
525  EXPECT_EQ(96u, orig_pixels[3][1]);
526  EXPECT_EQ(96u, orig_pixels[3][2]);
527  EXPECT_EQ(224u, orig_pixels[3][3]);
528
529  for (int i = 0; i < 256; ++i) {
530    orig_pixels[i][0] = i;
531    orig_pixels[i][1] = i / 2;
532    orig_pixels[i][2] = i / 3;
533    orig_pixels[i][3] = i;
534  }
535
536  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
537    ARGBGray(&orig_pixels[0][0], 0, 0, 0, 256, 1);
538  }
539}
540
541TEST_F(libyuvTest, TestARGBGrayTo) {
542  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
543  SIMD_ALIGNED(uint8 gray_pixels[256][4]);
544
545  // Test blue
546  orig_pixels[0][0] = 255u;
547  orig_pixels[0][1] = 0u;
548  orig_pixels[0][2] = 0u;
549  orig_pixels[0][3] = 128u;
550  // Test green
551  orig_pixels[1][0] = 0u;
552  orig_pixels[1][1] = 255u;
553  orig_pixels[1][2] = 0u;
554  orig_pixels[1][3] = 0u;
555  // Test red
556  orig_pixels[2][0] = 0u;
557  orig_pixels[2][1] = 0u;
558  orig_pixels[2][2] = 255u;
559  orig_pixels[2][3] = 255u;
560  // Test color
561  orig_pixels[3][0] = 16u;
562  orig_pixels[3][1] = 64u;
563  orig_pixels[3][2] = 192u;
564  orig_pixels[3][3] = 224u;
565  // Do 16 to test asm version.
566  ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 16, 1);
567  EXPECT_EQ(27u, gray_pixels[0][0]);
568  EXPECT_EQ(27u, gray_pixels[0][1]);
569  EXPECT_EQ(27u, gray_pixels[0][2]);
570  EXPECT_EQ(128u, gray_pixels[0][3]);
571  EXPECT_EQ(151u, gray_pixels[1][0]);
572  EXPECT_EQ(151u, gray_pixels[1][1]);
573  EXPECT_EQ(151u, gray_pixels[1][2]);
574  EXPECT_EQ(0u, gray_pixels[1][3]);
575  EXPECT_EQ(75u, gray_pixels[2][0]);
576  EXPECT_EQ(75u, gray_pixels[2][1]);
577  EXPECT_EQ(75u, gray_pixels[2][2]);
578  EXPECT_EQ(255u, gray_pixels[2][3]);
579  EXPECT_EQ(96u, gray_pixels[3][0]);
580  EXPECT_EQ(96u, gray_pixels[3][1]);
581  EXPECT_EQ(96u, gray_pixels[3][2]);
582  EXPECT_EQ(224u, gray_pixels[3][3]);
583
584  for (int i = 0; i < 256; ++i) {
585    orig_pixels[i][0] = i;
586    orig_pixels[i][1] = i / 2;
587    orig_pixels[i][2] = i / 3;
588    orig_pixels[i][3] = i;
589  }
590
591  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
592    ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 256, 1);
593  }
594}
595
596TEST_F(libyuvTest, TestARGBSepia) {
597  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
598
599  // Test blue
600  orig_pixels[0][0] = 255u;
601  orig_pixels[0][1] = 0u;
602  orig_pixels[0][2] = 0u;
603  orig_pixels[0][3] = 128u;
604  // Test green
605  orig_pixels[1][0] = 0u;
606  orig_pixels[1][1] = 255u;
607  orig_pixels[1][2] = 0u;
608  orig_pixels[1][3] = 0u;
609  // Test red
610  orig_pixels[2][0] = 0u;
611  orig_pixels[2][1] = 0u;
612  orig_pixels[2][2] = 255u;
613  orig_pixels[2][3] = 255u;
614  // Test color
615  orig_pixels[3][0] = 16u;
616  orig_pixels[3][1] = 64u;
617  orig_pixels[3][2] = 192u;
618  orig_pixels[3][3] = 224u;
619  // Do 16 to test asm version.
620  ARGBSepia(&orig_pixels[0][0], 0, 0, 0, 16, 1);
621  EXPECT_EQ(33u, orig_pixels[0][0]);
622  EXPECT_EQ(43u, orig_pixels[0][1]);
623  EXPECT_EQ(47u, orig_pixels[0][2]);
624  EXPECT_EQ(128u, orig_pixels[0][3]);
625  EXPECT_EQ(135u, orig_pixels[1][0]);
626  EXPECT_EQ(175u, orig_pixels[1][1]);
627  EXPECT_EQ(195u, orig_pixels[1][2]);
628  EXPECT_EQ(0u, orig_pixels[1][3]);
629  EXPECT_EQ(69u, orig_pixels[2][0]);
630  EXPECT_EQ(89u, orig_pixels[2][1]);
631  EXPECT_EQ(99u, orig_pixels[2][2]);
632  EXPECT_EQ(255u, orig_pixels[2][3]);
633  EXPECT_EQ(88u, orig_pixels[3][0]);
634  EXPECT_EQ(114u, orig_pixels[3][1]);
635  EXPECT_EQ(127u, orig_pixels[3][2]);
636  EXPECT_EQ(224u, orig_pixels[3][3]);
637
638  for (int i = 0; i < 256; ++i) {
639    orig_pixels[i][0] = i;
640    orig_pixels[i][1] = i / 2;
641    orig_pixels[i][2] = i / 3;
642    orig_pixels[i][3] = i;
643  }
644
645  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
646    ARGBSepia(&orig_pixels[0][0], 0, 0, 0, 256, 1);
647  }
648}
649
650TEST_F(libyuvTest, TestARGBColorMatrix) {
651  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
652
653  // Matrix for Sepia.
654  static const int8 kARGBToSepia[] = {
655    17, 68, 35, 0,
656    22, 88, 45, 0,
657    24, 98, 50, 0,
658  };
659
660  // Test blue
661  orig_pixels[0][0] = 255u;
662  orig_pixels[0][1] = 0u;
663  orig_pixels[0][2] = 0u;
664  orig_pixels[0][3] = 128u;
665  // Test green
666  orig_pixels[1][0] = 0u;
667  orig_pixels[1][1] = 255u;
668  orig_pixels[1][2] = 0u;
669  orig_pixels[1][3] = 0u;
670  // Test red
671  orig_pixels[2][0] = 0u;
672  orig_pixels[2][1] = 0u;
673  orig_pixels[2][2] = 255u;
674  orig_pixels[2][3] = 255u;
675  // Test color
676  orig_pixels[3][0] = 16u;
677  orig_pixels[3][1] = 64u;
678  orig_pixels[3][2] = 192u;
679  orig_pixels[3][3] = 224u;
680  // Do 16 to test asm version.
681  ARGBColorMatrix(&orig_pixels[0][0], 0, &kARGBToSepia[0], 0, 0, 16, 1);
682  EXPECT_EQ(33u, orig_pixels[0][0]);
683  EXPECT_EQ(43u, orig_pixels[0][1]);
684  EXPECT_EQ(47u, orig_pixels[0][2]);
685  EXPECT_EQ(128u, orig_pixels[0][3]);
686  EXPECT_EQ(135u, orig_pixels[1][0]);
687  EXPECT_EQ(175u, orig_pixels[1][1]);
688  EXPECT_EQ(195u, orig_pixels[1][2]);
689  EXPECT_EQ(0u, orig_pixels[1][3]);
690  EXPECT_EQ(69u, orig_pixels[2][0]);
691  EXPECT_EQ(89u, orig_pixels[2][1]);
692  EXPECT_EQ(99u, orig_pixels[2][2]);
693  EXPECT_EQ(255u, orig_pixels[2][3]);
694  EXPECT_EQ(88u, orig_pixels[3][0]);
695  EXPECT_EQ(114u, orig_pixels[3][1]);
696  EXPECT_EQ(127u, orig_pixels[3][2]);
697  EXPECT_EQ(224u, orig_pixels[3][3]);
698
699  for (int i = 0; i < 256; ++i) {
700    orig_pixels[i][0] = i;
701    orig_pixels[i][1] = i / 2;
702    orig_pixels[i][2] = i / 3;
703    orig_pixels[i][3] = i;
704  }
705
706  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
707    ARGBColorMatrix(&orig_pixels[0][0], 0, &kARGBToSepia[0], 0, 0, 256, 1);
708  }
709}
710
711TEST_F(libyuvTest, TestARGBColorTable) {
712  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
713  memset(orig_pixels, 0, sizeof(orig_pixels));
714
715  // Matrix for Sepia.
716  static const uint8 kARGBTable[256 * 4] = {
717    1u, 2u, 3u, 4u,
718    5u, 6u, 7u, 8u,
719    9u, 10u, 11u, 12u,
720    13u, 14u, 15u, 16u,
721  };
722
723  orig_pixels[0][0] = 0u;
724  orig_pixels[0][1] = 0u;
725  orig_pixels[0][2] = 0u;
726  orig_pixels[0][3] = 0u;
727  orig_pixels[1][0] = 1u;
728  orig_pixels[1][1] = 1u;
729  orig_pixels[1][2] = 1u;
730  orig_pixels[1][3] = 1u;
731  orig_pixels[2][0] = 2u;
732  orig_pixels[2][1] = 2u;
733  orig_pixels[2][2] = 2u;
734  orig_pixels[2][3] = 2u;
735  orig_pixels[3][0] = 0u;
736  orig_pixels[3][1] = 1u;
737  orig_pixels[3][2] = 2u;
738  orig_pixels[3][3] = 3u;
739  // Do 16 to test asm version.
740  ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1);
741  EXPECT_EQ(1u, orig_pixels[0][0]);
742  EXPECT_EQ(2u, orig_pixels[0][1]);
743  EXPECT_EQ(3u, orig_pixels[0][2]);
744  EXPECT_EQ(4u, orig_pixels[0][3]);
745  EXPECT_EQ(5u, orig_pixels[1][0]);
746  EXPECT_EQ(6u, orig_pixels[1][1]);
747  EXPECT_EQ(7u, orig_pixels[1][2]);
748  EXPECT_EQ(8u, orig_pixels[1][3]);
749  EXPECT_EQ(9u, orig_pixels[2][0]);
750  EXPECT_EQ(10u, orig_pixels[2][1]);
751  EXPECT_EQ(11u, orig_pixels[2][2]);
752  EXPECT_EQ(12u, orig_pixels[2][3]);
753  EXPECT_EQ(1u, orig_pixels[3][0]);
754  EXPECT_EQ(6u, orig_pixels[3][1]);
755  EXPECT_EQ(11u, orig_pixels[3][2]);
756  EXPECT_EQ(16u, orig_pixels[3][3]);
757
758  for (int i = 0; i < 256; ++i) {
759    orig_pixels[i][0] = i;
760    orig_pixels[i][1] = i / 2;
761    orig_pixels[i][2] = i / 3;
762    orig_pixels[i][3] = i;
763  }
764
765  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
766    ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 256, 1);
767  }
768}
769
770TEST_F(libyuvTest, TestARGBQuantize) {
771  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
772
773  for (int i = 0; i < 256; ++i) {
774    orig_pixels[i][0] = i;
775    orig_pixels[i][1] = i / 2;
776    orig_pixels[i][2] = i / 3;
777    orig_pixels[i][3] = i;
778  }
779  ARGBQuantize(&orig_pixels[0][0], 0,
780               (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0, 256, 1);
781
782  for (int i = 0; i < 256; ++i) {
783    EXPECT_EQ(i / 8 * 8 + 8 / 2, orig_pixels[i][0]);
784    EXPECT_EQ(i / 2 / 8 * 8 + 8 / 2, orig_pixels[i][1]);
785    EXPECT_EQ(i / 3 / 8 * 8 + 8 / 2, orig_pixels[i][2]);
786    EXPECT_EQ(i, orig_pixels[i][3]);
787  }
788  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
789    ARGBQuantize(&orig_pixels[0][0], 0,
790                 (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0, 256, 1);
791  }
792}
793
794TEST_F(libyuvTest, TestARGBMirror) {
795  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
796  SIMD_ALIGNED(uint8 dst_pixels[256][4]);
797
798  for (int i = 0; i < 256; ++i) {
799    orig_pixels[i][0] = i;
800    orig_pixels[i][1] = i / 2;
801    orig_pixels[i][2] = i / 3;
802    orig_pixels[i][3] = i / 4;
803  }
804  ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 256, 1);
805
806  for (int i = 0; i < 256; ++i) {
807    EXPECT_EQ(i, dst_pixels[255 - i][0]);
808    EXPECT_EQ(i / 2, dst_pixels[255 - i][1]);
809    EXPECT_EQ(i / 3, dst_pixels[255 - i][2]);
810    EXPECT_EQ(i / 4, dst_pixels[255 - i][3]);
811  }
812  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
813    ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 256, 1);
814  }
815}
816
817TEST_F(libyuvTest, TestShade) {
818  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
819  SIMD_ALIGNED(uint8 shade_pixels[256][4]);
820
821  orig_pixels[0][0] = 10u;
822  orig_pixels[0][1] = 20u;
823  orig_pixels[0][2] = 40u;
824  orig_pixels[0][3] = 80u;
825  orig_pixels[1][0] = 0u;
826  orig_pixels[1][1] = 0u;
827  orig_pixels[1][2] = 0u;
828  orig_pixels[1][3] = 255u;
829  orig_pixels[2][0] = 0u;
830  orig_pixels[2][1] = 0u;
831  orig_pixels[2][2] = 0u;
832  orig_pixels[2][3] = 0u;
833  orig_pixels[3][0] = 0u;
834  orig_pixels[3][1] = 0u;
835  orig_pixels[3][2] = 0u;
836  orig_pixels[3][3] = 0u;
837  ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 4, 1, 0x80ffffff);
838  EXPECT_EQ(10u, shade_pixels[0][0]);
839  EXPECT_EQ(20u, shade_pixels[0][1]);
840  EXPECT_EQ(40u, shade_pixels[0][2]);
841  EXPECT_EQ(40u, shade_pixels[0][3]);
842  EXPECT_EQ(0u, shade_pixels[1][0]);
843  EXPECT_EQ(0u, shade_pixels[1][1]);
844  EXPECT_EQ(0u, shade_pixels[1][2]);
845  EXPECT_EQ(128u, shade_pixels[1][3]);
846  EXPECT_EQ(0u, shade_pixels[2][0]);
847  EXPECT_EQ(0u, shade_pixels[2][1]);
848  EXPECT_EQ(0u, shade_pixels[2][2]);
849  EXPECT_EQ(0u, shade_pixels[2][3]);
850  EXPECT_EQ(0u, shade_pixels[3][0]);
851  EXPECT_EQ(0u, shade_pixels[3][1]);
852  EXPECT_EQ(0u, shade_pixels[3][2]);
853  EXPECT_EQ(0u, shade_pixels[3][3]);
854
855  ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 4, 1, 0x80808080);
856  EXPECT_EQ(5u, shade_pixels[0][0]);
857  EXPECT_EQ(10u, shade_pixels[0][1]);
858  EXPECT_EQ(20u, shade_pixels[0][2]);
859  EXPECT_EQ(40u, shade_pixels[0][3]);
860
861  for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
862    ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 256, 1,
863              0x80808080);
864  }
865}
866
867TEST_F(libyuvTest, TestInterpolate) {
868  SIMD_ALIGNED(uint8 orig_pixels_0[256][4]);
869  SIMD_ALIGNED(uint8 orig_pixels_1[256][4]);
870  SIMD_ALIGNED(uint8 interpolate_pixels[256][4]);
871
872  orig_pixels_0[0][0] = 16u;
873  orig_pixels_0[0][1] = 32u;
874  orig_pixels_0[0][2] = 64u;
875  orig_pixels_0[0][3] = 128u;
876  orig_pixels_0[1][0] = 0u;
877  orig_pixels_0[1][1] = 0u;
878  orig_pixels_0[1][2] = 0u;
879  orig_pixels_0[1][3] = 255u;
880  orig_pixels_0[2][0] = 0u;
881  orig_pixels_0[2][1] = 0u;
882  orig_pixels_0[2][2] = 0u;
883  orig_pixels_0[2][3] = 0u;
884  orig_pixels_0[3][0] = 0u;
885  orig_pixels_0[3][1] = 0u;
886  orig_pixels_0[3][2] = 0u;
887  orig_pixels_0[3][3] = 0u;
888
889  orig_pixels_1[0][0] = 0u;
890  orig_pixels_1[0][1] = 0u;
891  orig_pixels_1[0][2] = 0u;
892  orig_pixels_1[0][3] = 0u;
893  orig_pixels_1[1][0] = 0u;
894  orig_pixels_1[1][1] = 0u;
895  orig_pixels_1[1][2] = 0u;
896  orig_pixels_1[1][3] = 0u;
897  orig_pixels_1[2][0] = 0u;
898  orig_pixels_1[2][1] = 0u;
899  orig_pixels_1[2][2] = 0u;
900  orig_pixels_1[2][3] = 0u;
901  orig_pixels_1[3][0] = 255u;
902  orig_pixels_1[3][1] = 255u;
903  orig_pixels_1[3][2] = 255u;
904  orig_pixels_1[3][3] = 255u;
905
906  ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
907                  &interpolate_pixels[0][0], 0, 4, 1, 128);
908  EXPECT_EQ(8u, interpolate_pixels[0][0]);
909  EXPECT_EQ(16u, interpolate_pixels[0][1]);
910  EXPECT_EQ(32u, interpolate_pixels[0][2]);
911  EXPECT_EQ(64u, interpolate_pixels[0][3]);
912  EXPECT_EQ(0u, interpolate_pixels[1][0]);
913  EXPECT_EQ(0u, interpolate_pixels[1][1]);
914  EXPECT_EQ(0u, interpolate_pixels[1][2]);
915  EXPECT_NEAR(128u, interpolate_pixels[1][3], 1);  // C = 127, SSE = 128.
916  EXPECT_EQ(0u, interpolate_pixels[2][0]);
917  EXPECT_EQ(0u, interpolate_pixels[2][1]);
918  EXPECT_EQ(0u, interpolate_pixels[2][2]);
919  EXPECT_EQ(0u, interpolate_pixels[2][3]);
920  EXPECT_NEAR(128u, interpolate_pixels[3][0], 1);
921  EXPECT_NEAR(128u, interpolate_pixels[3][1], 1);
922  EXPECT_NEAR(128u, interpolate_pixels[3][2], 1);
923  EXPECT_NEAR(128u, interpolate_pixels[3][3], 1);
924
925  ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
926                  &interpolate_pixels[0][0], 0, 4, 1, 0);
927  EXPECT_EQ(16u, interpolate_pixels[0][0]);
928  EXPECT_EQ(32u, interpolate_pixels[0][1]);
929  EXPECT_EQ(64u, interpolate_pixels[0][2]);
930  EXPECT_EQ(128u, interpolate_pixels[0][3]);
931
932  ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
933                  &interpolate_pixels[0][0], 0, 4, 1, 192);
934
935  EXPECT_EQ(4u, interpolate_pixels[0][0]);
936  EXPECT_EQ(8u, interpolate_pixels[0][1]);
937  EXPECT_EQ(16u, interpolate_pixels[0][2]);
938  EXPECT_EQ(32u, interpolate_pixels[0][3]);
939
940  for (int i = 0; i < benchmark_iterations_ * (1280 * 720 / 256); ++i) {
941    ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0,
942                    &interpolate_pixels[0][0], 0, 256, 1, 128);
943  }
944}
945
946TEST_F(libyuvTest, TestAffine) {
947  SIMD_ALIGNED(uint8 orig_pixels_0[256][4]);
948  SIMD_ALIGNED(uint8 interpolate_pixels_C[256][4]);
949#if defined(HAS_ARGBAFFINEROW_SSE2)
950  SIMD_ALIGNED(uint8 interpolate_pixels_Opt[256][4]);
951#endif
952
953  for (int i = 0; i < 256; ++i) {
954    for (int j = 0; j < 4; ++j) {
955      orig_pixels_0[i][j] = i;
956    }
957  }
958
959  float uv_step[4] = { 0.f, 0.f, 0.75f, 0.f };
960
961  ARGBAffineRow_C(&orig_pixels_0[0][0], 0, &interpolate_pixels_C[0][0],
962                  uv_step, 256);
963  EXPECT_EQ(0u, interpolate_pixels_C[0][0]);
964  EXPECT_EQ(96u, interpolate_pixels_C[128][0]);
965  EXPECT_EQ(191u, interpolate_pixels_C[255][3]);
966
967#if defined(HAS_ARGBAFFINEROW_SSE2)
968  ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0],
969                     uv_step, 256);
970  EXPECT_EQ(0, memcmp(interpolate_pixels_Opt, interpolate_pixels_C, 256 * 4));
971#endif
972
973#if defined(HAS_ARGBAFFINEROW_SSE2)
974  int has_sse2 = TestCpuFlag(kCpuHasSSE2);
975  if (has_sse2) {
976    for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
977      ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0],
978                         uv_step, 256);
979    }
980  } else {
981#endif
982    for (int i = 0; i < benchmark_iterations_ * 1280 * 720 / 256; ++i) {
983      ARGBAffineRow_C(&orig_pixels_0[0][0], 0, &interpolate_pixels_C[0][0],
984                      uv_step, 256);
985    }
986#if defined(HAS_ARGBAFFINEROW_SSE2)
987  }
988#endif
989}
990
991TEST_F(libyuvTest, Test565) {
992  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
993  SIMD_ALIGNED(uint8 pixels565[256][2]);
994
995  for (int i = 0; i < 256; ++i) {
996    for (int j = 0; j < 4; ++j) {
997      orig_pixels[i][j] = i;
998    }
999  }
1000  ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1);
1001  uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381);
1002  EXPECT_EQ(610919429u, checksum);
1003}
1004
1005}  // namespace libyuv
1006