Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libyuv / unit_test / convert_test.cc
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 #ifdef HAVE_JPEG
22 #include "libyuv/mjpeg_decoder.h"
23 #endif
24 #include "libyuv/planar_functions.h"
25 #include "libyuv/rotate.h"
26 #include "libyuv/row.h"
27 #include "libyuv/video_common.h"
28 #include "../unit_test/unit_test.h"
29
30 #if defined(_MSC_VER)
31 #define SIMD_ALIGNED(var) __declspec(align(16)) var
32 #else  // __GNUC__
33 #define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
34 #endif
35
36 namespace libyuv {
37
38 #define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
39
40 #define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,           \
41                        FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF)   \
42 TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {                        \
43   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
44   const int kHeight = benchmark_height_;                                       \
45   align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
46   align_buffer_64(src_u,                                                       \
47                   SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
48                   SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
49   align_buffer_64(src_v,                                                       \
50                   SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
51                   SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
52   align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
53   align_buffer_64(dst_u_c,                                                     \
54                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
55                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
56   align_buffer_64(dst_v_c,                                                     \
57                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
58                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
59   align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
60   align_buffer_64(dst_u_opt,                                                   \
61                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
62                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
63   align_buffer_64(dst_v_opt,                                                   \
64                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
65                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
66   srandom(time(NULL));                                                         \
67   for (int i = 0; i < kHeight; ++i)                                            \
68     for (int j = 0; j < kWidth; ++j)                                           \
69       src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
70   for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) {                \
71     for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) {               \
72       src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
73           (random() & 0xff);                                                   \
74       src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
75           (random() & 0xff);                                                   \
76     }                                                                          \
77   }                                                                            \
78   memset(dst_y_c, 1, kWidth * kHeight);                                        \
79   memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
80                      SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
81   memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
82                      SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
83   memset(dst_y_opt, 101, kWidth * kHeight);                                    \
84   memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
85                          SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
86   memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
87                          SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
88   MaskCpuFlags(0);                                                             \
89   SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                          \
90                                  src_u + OFF,                                  \
91                                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
92                                  src_v + OFF,                                  \
93                                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
94                                  dst_y_c, kWidth,                              \
95                                  dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
96                                  dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
97                                  kWidth, NEG kHeight);                         \
98   MaskCpuFlags(-1);                                                            \
99   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
100     SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                        \
101                                    src_u + OFF,                                \
102                                        SUBSAMPLE(kWidth, SRC_SUBSAMP_X),       \
103                                    src_v + OFF,                                \
104                                        SUBSAMPLE(kWidth, SRC_SUBSAMP_X),       \
105                                    dst_y_opt, kWidth,                          \
106                                    dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
107                                    dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
108                                    kWidth, NEG kHeight);                       \
109   }                                                                            \
110   int max_diff = 0;                                                            \
111   for (int i = 0; i < kHeight; ++i) {                                          \
112     for (int j = 0; j < kWidth; ++j) {                                         \
113       int abs_diff =                                                           \
114           abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
115               static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
116       if (abs_diff > max_diff) {                                               \
117         max_diff = abs_diff;                                                   \
118       }                                                                        \
119     }                                                                          \
120   }                                                                            \
121   EXPECT_EQ(0, max_diff);                                                      \
122   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
123     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
124       int abs_diff =                                                           \
125           abs(static_cast<int>(dst_u_c[i *                                     \
126                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
127               static_cast<int>(dst_u_opt[i *                                   \
128                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
129       if (abs_diff > max_diff) {                                               \
130         max_diff = abs_diff;                                                   \
131       }                                                                        \
132     }                                                                          \
133   }                                                                            \
134   EXPECT_LE(max_diff, 3);                                                      \
135   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
136     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
137       int abs_diff =                                                           \
138           abs(static_cast<int>(dst_v_c[i *                                     \
139                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
140               static_cast<int>(dst_v_opt[i *                                   \
141                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
142       if (abs_diff > max_diff) {                                               \
143         max_diff = abs_diff;                                                   \
144       }                                                                        \
145     }                                                                          \
146   }                                                                            \
147   EXPECT_LE(max_diff, 3);                                                      \
148   free_aligned_buffer_64(dst_y_c);                                             \
149   free_aligned_buffer_64(dst_u_c);                                             \
150   free_aligned_buffer_64(dst_v_c);                                             \
151   free_aligned_buffer_64(dst_y_opt);                                           \
152   free_aligned_buffer_64(dst_u_opt);                                           \
153   free_aligned_buffer_64(dst_v_opt);                                           \
154   free_aligned_buffer_64(src_y);                                               \
155   free_aligned_buffer_64(src_u);                                               \
156   free_aligned_buffer_64(src_v);                                               \
157 }
158
159 #define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,            \
160                       FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)                        \
161     TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
162                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
163                    benchmark_width_ - 4, _Any, +, 0)                           \
164     TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
165                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
166                    benchmark_width_, _Unaligned, +, 1)                         \
167     TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
168                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
169                    benchmark_width_, _Invert, -, 0)                            \
170     TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
171                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
172                    benchmark_width_, _Opt, +, 0)
173
174 TESTPLANARTOP(I420, 2, 2, I420, 2, 2)
175 TESTPLANARTOP(I422, 2, 1, I420, 2, 2)
176 TESTPLANARTOP(I444, 1, 1, I420, 2, 2)
177 TESTPLANARTOP(I411, 4, 1, I420, 2, 2)
178 TESTPLANARTOP(I420, 2, 2, I422, 2, 1)
179 TESTPLANARTOP(I420, 2, 2, I444, 1, 1)
180 TESTPLANARTOP(I420, 2, 2, I411, 4, 1)
181 TESTPLANARTOP(I420, 2, 2, I420Mirror, 2, 2)
182 TESTPLANARTOP(I422, 2, 1, I422, 2, 1)
183 TESTPLANARTOP(I444, 1, 1, I444, 1, 1)
184
185 #define TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,          \
186                        FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF)   \
187 TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {                        \
188   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
189   const int kHeight = benchmark_height_;                                       \
190   align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
191   align_buffer_64(src_u,                                                       \
192                   SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
193                   SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
194   align_buffer_64(src_v,                                                       \
195                   SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
196                   SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
197   align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
198   align_buffer_64(dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *                 \
199                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
200   align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
201   align_buffer_64(dst_uv_opt, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *               \
202                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
203   srandom(time(NULL));                                                         \
204   for (int i = 0; i < kHeight; ++i)                                            \
205     for (int j = 0; j < kWidth; ++j)                                           \
206       src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
207   for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) {                \
208     for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) {               \
209       src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
210           (random() & 0xff);                                                   \
211       src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
212           (random() & 0xff);                                                   \
213     }                                                                          \
214   }                                                                            \
215   memset(dst_y_c, 1, kWidth * kHeight);                                        \
216   memset(dst_uv_c, 2, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *                       \
217                       SUBSAMPLE(kHeight, SUBSAMP_Y));                          \
218   memset(dst_y_opt, 101, kWidth * kHeight);                                    \
219   memset(dst_uv_opt, 102, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *                   \
220                           SUBSAMPLE(kHeight, SUBSAMP_Y));                      \
221   MaskCpuFlags(0);                                                             \
222   SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                          \
223                                  src_u + OFF,                                  \
224                                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
225                                  src_v + OFF,                                  \
226                                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
227                                  dst_y_c, kWidth,                              \
228                                  dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X),   \
229                                  kWidth, NEG kHeight);                         \
230   MaskCpuFlags(-1);                                                            \
231   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
232     SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                        \
233                                    src_u + OFF,                                \
234                                    SUBSAMPLE(kWidth, SRC_SUBSAMP_X),           \
235                                    src_v + OFF,                                \
236                                    SUBSAMPLE(kWidth, SRC_SUBSAMP_X),           \
237                                    dst_y_opt, kWidth,                          \
238                                    dst_uv_opt,                                 \
239                                    SUBSAMPLE(kWidth * 2, SUBSAMP_X),           \
240                                    kWidth, NEG kHeight);                       \
241   }                                                                            \
242   int max_diff = 0;                                                            \
243   for (int i = 0; i < kHeight; ++i) {                                          \
244     for (int j = 0; j < kWidth; ++j) {                                         \
245       int abs_diff =                                                           \
246           abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
247               static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
248       if (abs_diff > max_diff) {                                               \
249         max_diff = abs_diff;                                                   \
250       }                                                                        \
251     }                                                                          \
252   }                                                                            \
253   EXPECT_LE(max_diff, 1);                                                      \
254   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
255     for (int j = 0; j < SUBSAMPLE(kWidth * 2, SUBSAMP_X); ++j) {               \
256       int abs_diff =                                                           \
257           abs(static_cast<int>(dst_uv_c[i *                                    \
258                                SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j]) -        \
259               static_cast<int>(dst_uv_opt[i *                                  \
260                                SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j]));        \
261       if (abs_diff > max_diff) {                                               \
262         max_diff = abs_diff;                                                   \
263       }                                                                        \
264     }                                                                          \
265   }                                                                            \
266   EXPECT_LE(max_diff, 1);                                                      \
267   free_aligned_buffer_64(dst_y_c);                                             \
268   free_aligned_buffer_64(dst_uv_c);                                            \
269   free_aligned_buffer_64(dst_y_opt);                                           \
270   free_aligned_buffer_64(dst_uv_opt);                                          \
271   free_aligned_buffer_64(src_y);                                               \
272   free_aligned_buffer_64(src_u);                                               \
273   free_aligned_buffer_64(src_v);                                               \
274 }
275
276 #define TESTPLANARTOBP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,           \
277                        FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)                       \
278     TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
279                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
280                     benchmark_width_ - 4, _Any, +, 0)                          \
281     TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
282                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
283                     benchmark_width_, _Unaligned, +, 1)                        \
284     TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
285                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
286                     benchmark_width_, _Invert, -, 0)                           \
287     TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
288                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
289                     benchmark_width_, _Opt, +, 0)
290
291 TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2)
292 TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2)
293
294 #define TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,         \
295                          FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \
296 TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {                        \
297   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
298   const int kHeight = benchmark_height_;                                       \
299   align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
300   align_buffer_64(src_uv, 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *               \
301                   SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
302   align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
303   align_buffer_64(dst_u_c,                                                     \
304                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
305                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
306   align_buffer_64(dst_v_c,                                                     \
307                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
308                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
309   align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
310   align_buffer_64(dst_u_opt,                                                   \
311                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
312                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
313   align_buffer_64(dst_v_opt,                                                   \
314                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
315                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
316   srandom(time(NULL));                                                         \
317   for (int i = 0; i < kHeight; ++i)                                            \
318     for (int j = 0; j < kWidth; ++j)                                           \
319       src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
320   for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) {                \
321     for (int j = 0; j < 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) {           \
322       src_uv[(i * 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =           \
323           (random() & 0xff);                                                   \
324     }                                                                          \
325   }                                                                            \
326   memset(dst_y_c, 1, kWidth * kHeight);                                        \
327   memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
328                      SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
329   memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
330                      SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
331   memset(dst_y_opt, 101, kWidth * kHeight);                                    \
332   memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
333                          SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
334   memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
335                          SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
336   MaskCpuFlags(0);                                                             \
337   SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                          \
338                                  src_uv + OFF,                                 \
339                                  2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X),         \
340                                  dst_y_c, kWidth,                              \
341                                  dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
342                                  dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
343                                  kWidth, NEG kHeight);                         \
344   MaskCpuFlags(-1);                                                            \
345   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
346     SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                        \
347                                    src_uv + OFF,                               \
348                                    2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X),       \
349                                    dst_y_opt, kWidth,                          \
350                                    dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
351                                    dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
352                                    kWidth, NEG kHeight);                       \
353   }                                                                            \
354   int max_diff = 0;                                                            \
355   for (int i = 0; i < kHeight; ++i) {                                          \
356     for (int j = 0; j < kWidth; ++j) {                                         \
357       int abs_diff =                                                           \
358           abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
359               static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
360       if (abs_diff > max_diff) {                                               \
361         max_diff = abs_diff;                                                   \
362       }                                                                        \
363     }                                                                          \
364   }                                                                            \
365   EXPECT_LE(max_diff, 1);                                                      \
366   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
367     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
368       int abs_diff =                                                           \
369           abs(static_cast<int>(dst_u_c[i *                                     \
370                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
371               static_cast<int>(dst_u_opt[i *                                   \
372                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
373       if (abs_diff > max_diff) {                                               \
374         max_diff = abs_diff;                                                   \
375       }                                                                        \
376     }                                                                          \
377   }                                                                            \
378   EXPECT_LE(max_diff, 1);                                                      \
379   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
380     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
381       int abs_diff =                                                           \
382           abs(static_cast<int>(dst_v_c[i *                                     \
383                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
384               static_cast<int>(dst_v_opt[i *                                   \
385                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
386       if (abs_diff > max_diff) {                                               \
387         max_diff = abs_diff;                                                   \
388       }                                                                        \
389     }                                                                          \
390   }                                                                            \
391   EXPECT_LE(max_diff, 1);                                                      \
392   free_aligned_buffer_64(dst_y_c);                                             \
393   free_aligned_buffer_64(dst_u_c);                                             \
394   free_aligned_buffer_64(dst_v_c);                                             \
395   free_aligned_buffer_64(dst_y_opt);                                           \
396   free_aligned_buffer_64(dst_u_opt);                                           \
397   free_aligned_buffer_64(dst_v_opt);                                           \
398   free_aligned_buffer_64(src_y);                                               \
399   free_aligned_buffer_64(src_uv);                                              \
400 }
401
402 #define TESTBIPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,          \
403                         FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)                      \
404     TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
405                      FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
406                      benchmark_width_ - 4, _Any, +, 0)                         \
407     TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
408                      FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
409                      benchmark_width_, _Unaligned, +, 1)                       \
410     TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
411                      FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
412                      benchmark_width_, _Invert, -, 0)                          \
413     TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
414                      FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
415                      benchmark_width_, _Opt, +, 0)
416
417 TESTBIPLANARTOP(NV12, 2, 2, I420, 2, 2)
418 TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2)
419
420 #define ALIGNINT(V, ALIGN) (((V) + (ALIGN) - 1) / (ALIGN) * (ALIGN))
421
422 #define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,  \
423                        YALIGN, W1280, DIFF, N, NEG, OFF, FMT_C, BPP_C)         \
424 TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) {                                 \
425   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
426   const int kHeight = ALIGNINT(benchmark_height_, YALIGN);                     \
427   const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN);                        \
428   const int kSizeUV =                                                          \
429     SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y);              \
430   align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
431   align_buffer_64(src_u, kSizeUV + OFF);                                       \
432   align_buffer_64(src_v, kSizeUV + OFF);                                       \
433   align_buffer_64(dst_argb_c, kStrideB * kHeight);                             \
434   align_buffer_64(dst_argb_opt, kStrideB * kHeight);                           \
435   srandom(time(NULL));                                                         \
436   for (int i = 0; i < kWidth * kHeight; ++i) {                                 \
437     src_y[i + OFF] = (random() & 0xff);                                        \
438   }                                                                            \
439   for (int i = 0; i < kSizeUV; ++i) {                                          \
440     src_u[i + OFF] = (random() & 0xff);                                        \
441     src_v[i + OFF] = (random() & 0xff);                                        \
442   }                                                                            \
443   memset(dst_argb_c, 1, kStrideB * kHeight);                                   \
444   memset(dst_argb_opt, 101, kStrideB * kHeight);                               \
445   MaskCpuFlags(0);                                                             \
446   FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                   \
447                         src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),             \
448                         src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),             \
449                         dst_argb_c, kStrideB,                                  \
450                         kWidth, NEG kHeight);                                  \
451   MaskCpuFlags(-1);                                                            \
452   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
453     FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                 \
454                           src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),           \
455                           src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),           \
456                           dst_argb_opt, kStrideB,                              \
457                           kWidth, NEG kHeight);                                \
458   }                                                                            \
459   int max_diff = 0;                                                            \
460   /* Convert to ARGB so 565 is expanded to bytes that can be compared. */      \
461   align_buffer_64(dst_argb32_c, kWidth * BPP_C  * kHeight);                    \
462   align_buffer_64(dst_argb32_opt, kWidth * BPP_C  * kHeight);                  \
463   memset(dst_argb32_c, 2, kWidth * BPP_C  * kHeight);                          \
464   memset(dst_argb32_opt, 102, kWidth * BPP_C  * kHeight);                      \
465   FMT_B##To##FMT_C(dst_argb_c, kStrideB,                                       \
466                    dst_argb32_c, kWidth * BPP_C ,                              \
467                    kWidth, kHeight);                                           \
468   FMT_B##To##FMT_C(dst_argb_opt, kStrideB,                                     \
469                    dst_argb32_opt, kWidth * BPP_C ,                            \
470                    kWidth, kHeight);                                           \
471   for (int i = 0; i < kWidth * BPP_C * kHeight; ++i) {                         \
472     int abs_diff =                                                             \
473         abs(static_cast<int>(dst_argb32_c[i]) -                                \
474             static_cast<int>(dst_argb32_opt[i]));                              \
475     if (abs_diff > max_diff) {                                                 \
476       max_diff = abs_diff;                                                     \
477     }                                                                          \
478   }                                                                            \
479   EXPECT_LE(max_diff, DIFF);                                                   \
480   free_aligned_buffer_64(src_y);                                               \
481   free_aligned_buffer_64(src_u);                                               \
482   free_aligned_buffer_64(src_v);                                               \
483   free_aligned_buffer_64(dst_argb_c);                                          \
484   free_aligned_buffer_64(dst_argb_opt);                                        \
485   free_aligned_buffer_64(dst_argb32_c);                                        \
486   free_aligned_buffer_64(dst_argb32_opt);                                      \
487 }
488
489 #define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,   \
490                       YALIGN, DIFF, FMT_C, BPP_C)                              \
491     TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
492         YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, FMT_C, BPP_C)          \
493     TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
494         YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, FMT_C, BPP_C)        \
495     TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
496         YALIGN, benchmark_width_, DIFF, _Invert, -, 0, FMT_C, BPP_C)           \
497     TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
498         YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C)
499
500 // TODO(fbarchard): Make vertical alignment unnecessary on bayer.
501 TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4)
502 TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4, 1, 2, ARGB, 4)
503 TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4)
504 TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1, 2, ARGB, 4)
505 TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1, 2, ARGB, 4)
506 TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1, 2, ARGB, 4)
507 TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4)
508 TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2, 1, 9, ARGB, 4)
509 TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2, 1, 17, ARGB, 4)
510 TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
511 TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4, 1, 2, ARGB, 4)
512 TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4)
513 TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4, 1, 2, ARGB, 4)
514 TESTPLANARTOB(I411, 4, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
515 TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
516 TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4, 1, 1, ARGB, 4)
517 TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4, 1, 1, ARGB, 4)
518 TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1, 0, ARGB, 4)
519 TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1, 0, ARGB, 4)
520 TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1, 0, ARGB, 4)
521 TESTPLANARTOB(I420, 2, 2, BayerBGGR, 1, 2, 2, 2, ARGB, 4)
522 TESTPLANARTOB(I420, 2, 2, BayerRGGB, 1, 2, 2, 2, ARGB, 4)
523 TESTPLANARTOB(I420, 2, 2, BayerGBRG, 1, 2, 2, 2, ARGB, 4)
524 TESTPLANARTOB(I420, 2, 2, BayerGRBG, 1, 2, 2, 2, ARGB, 4)
525
526 #define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,       \
527                          W1280, DIFF, N, NEG, OFF)                             \
528 TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) {                                 \
529   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
530   const int kHeight = benchmark_height_;                                       \
531   const int kStrideB = kWidth * BPP_B;                                         \
532   align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
533   align_buffer_64(src_uv,                                                      \
534                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
535                   SUBSAMPLE(kHeight, SUBSAMP_Y) * 2 + OFF);                    \
536   align_buffer_64(dst_argb_c, kStrideB * kHeight);                             \
537   align_buffer_64(dst_argb_opt, kStrideB * kHeight);                           \
538   srandom(time(NULL));                                                         \
539   for (int i = 0; i < kHeight; ++i)                                            \
540     for (int j = 0; j < kWidth; ++j)                                           \
541       src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
542   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
543     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) {               \
544       src_uv[(i * SUBSAMPLE(kWidth, SUBSAMP_X)) * 2 + j + OFF] =               \
545           (random() & 0xff);                                                   \
546     }                                                                          \
547   }                                                                            \
548   memset(dst_argb_c, 1, kStrideB * kHeight);                                   \
549   memset(dst_argb_opt, 101, kStrideB * kHeight);                               \
550   MaskCpuFlags(0);                                                             \
551   FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                   \
552                         src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,        \
553                         dst_argb_c, kWidth * BPP_B,                            \
554                         kWidth, NEG kHeight);                                  \
555   MaskCpuFlags(-1);                                                            \
556   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
557     FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                 \
558                           src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,      \
559                           dst_argb_opt, kWidth * BPP_B,                        \
560                           kWidth, NEG kHeight);                                \
561   }                                                                            \
562   /* Convert to ARGB so 565 is expanded to bytes that can be compared. */      \
563   align_buffer_64(dst_argb32_c, kWidth * 4 * kHeight);                         \
564   align_buffer_64(dst_argb32_opt, kWidth * 4 * kHeight);                       \
565   memset(dst_argb32_c, 2, kWidth * 4 * kHeight);                               \
566   memset(dst_argb32_opt, 102, kWidth * 4 * kHeight);                           \
567   FMT_B##ToARGB(dst_argb_c, kStrideB,                                          \
568                 dst_argb32_c, kWidth * 4,                                      \
569                 kWidth, kHeight);                                              \
570   FMT_B##ToARGB(dst_argb_opt, kStrideB,                                        \
571                 dst_argb32_opt, kWidth * 4,                                    \
572                 kWidth, kHeight);                                              \
573   int max_diff = 0;                                                            \
574   for (int i = 0; i < kHeight; ++i) {                                          \
575     for (int j = 0; j < kWidth * 4; ++j) {                                     \
576       int abs_diff =                                                           \
577           abs(static_cast<int>(dst_argb32_c[i * kWidth * 4 + j]) -             \
578               static_cast<int>(dst_argb32_opt[i * kWidth * 4 + j]));           \
579       if (abs_diff > max_diff) {                                               \
580         max_diff = abs_diff;                                                   \
581       }                                                                        \
582     }                                                                          \
583   }                                                                            \
584   EXPECT_LE(max_diff, DIFF);                                                   \
585   free_aligned_buffer_64(src_y);                                               \
586   free_aligned_buffer_64(src_uv);                                              \
587   free_aligned_buffer_64(dst_argb_c);                                          \
588   free_aligned_buffer_64(dst_argb_opt);                                        \
589   free_aligned_buffer_64(dst_argb32_c);                                        \
590   free_aligned_buffer_64(dst_argb32_opt);                                      \
591 }
592
593 #define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, DIFF)  \
594     TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
595                      benchmark_width_ - 4, DIFF, _Any, +, 0)                   \
596     TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
597                      benchmark_width_, DIFF, _Unaligned, +, 1)                 \
598     TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
599                      benchmark_width_, DIFF, _Invert, -, 0)                    \
600     TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
601                      benchmark_width_, DIFF, _Opt, +, 0)
602
603 TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4, 2)
604 TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4, 2)
605 TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9)
606 TESTBIPLANARTOB(NV21, 2, 2, RGB565, 2, 9)
607
608 #define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
609                        W1280, DIFF, N, NEG, OFF)                               \
610 TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) {                                 \
611   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
612   const int kHeight = ALIGNINT(benchmark_height_, YALIGN);                     \
613   const int kStride =                                                          \
614       (SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMP_X * 8 * BPP_A + 7) / 8;          \
615   align_buffer_64(src_argb, kStride * kHeight + OFF);                          \
616   align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
617   align_buffer_64(dst_u_c,                                                     \
618                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
619                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
620   align_buffer_64(dst_v_c,                                                     \
621                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
622                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
623   align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
624   align_buffer_64(dst_u_opt,                                                   \
625                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
626                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
627   align_buffer_64(dst_v_opt,                                                   \
628                   SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
629                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
630   memset(dst_y_c, 1, kWidth * kHeight);                                        \
631   memset(dst_u_c, 2,                                                           \
632          SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
633   memset(dst_v_c, 3,                                                           \
634          SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
635   memset(dst_y_opt, 101, kWidth * kHeight);                                    \
636   memset(dst_u_opt, 102,                                                       \
637          SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
638   memset(dst_v_opt, 103,                                                       \
639          SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
640   srandom(time(NULL));                                                         \
641   for (int i = 0; i < kHeight; ++i)                                            \
642     for (int j = 0; j < kStride; ++j)                                          \
643       src_argb[(i * kStride) + j + OFF] = (random() & 0xff);                   \
644   MaskCpuFlags(0);                                                             \
645   FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                               \
646                         dst_y_c, kWidth,                                       \
647                         dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X),                 \
648                         dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X),                 \
649                         kWidth, NEG kHeight);                                  \
650   MaskCpuFlags(-1);                                                            \
651   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
652     FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                             \
653                           dst_y_opt, kWidth,                                   \
654                           dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X),             \
655                           dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X),             \
656                           kWidth, NEG kHeight);                                \
657   }                                                                            \
658   int max_diff = 0;                                                            \
659   for (int i = 0; i < kHeight; ++i) {                                          \
660     for (int j = 0; j < kWidth; ++j) {                                         \
661       int abs_diff =                                                           \
662           abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
663               static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
664       if (abs_diff > max_diff) {                                               \
665         max_diff = abs_diff;                                                   \
666       }                                                                        \
667     }                                                                          \
668   }                                                                            \
669   EXPECT_LE(max_diff, DIFF);                                                   \
670   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
671     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
672       int abs_diff =                                                           \
673           abs(static_cast<int>(dst_u_c[i *                                     \
674                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
675               static_cast<int>(dst_u_opt[i *                                   \
676                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
677       if (abs_diff > max_diff) {                                               \
678         max_diff = abs_diff;                                                   \
679       }                                                                        \
680     }                                                                          \
681   }                                                                            \
682   EXPECT_LE(max_diff, DIFF);                                                   \
683   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
684     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
685       int abs_diff =                                                           \
686           abs(static_cast<int>(dst_v_c[i *                                     \
687                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
688               static_cast<int>(dst_v_opt[i *                                   \
689                                SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
690       if (abs_diff > max_diff) {                                               \
691         max_diff = abs_diff;                                                   \
692       }                                                                        \
693     }                                                                          \
694   }                                                                            \
695   EXPECT_LE(max_diff, DIFF);                                                   \
696   free_aligned_buffer_64(dst_y_c);                                             \
697   free_aligned_buffer_64(dst_u_c);                                             \
698   free_aligned_buffer_64(dst_v_c);                                             \
699   free_aligned_buffer_64(dst_y_opt);                                           \
700   free_aligned_buffer_64(dst_u_opt);                                           \
701   free_aligned_buffer_64(dst_v_opt);                                           \
702   free_aligned_buffer_64(src_argb);                                            \
703 }
704
705 #define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,  \
706                       DIFF)                                                    \
707     TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
708                    benchmark_width_ - 4, DIFF, _Any, +, 0)                     \
709     TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
710                    benchmark_width_, DIFF, _Unaligned, +, 1)                   \
711     TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
712                    benchmark_width_, DIFF, _Invert, -, 0)                      \
713     TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
714                    benchmark_width_, DIFF, _Opt, +, 0)
715
716 TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2, 4)
717 #ifdef __arm__
718 TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 4)
719 #else
720 TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 0)
721 #endif
722 TESTATOPLANAR(BGRA, 4, 1, I420, 2, 2, 4)
723 TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2, 4)
724 TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2, 4)
725 TESTATOPLANAR(RAW, 3, 1, I420, 2, 2, 4)
726 TESTATOPLANAR(RGB24, 3, 1, I420, 2, 2, 4)
727 TESTATOPLANAR(RGB565, 2, 1, I420, 2, 2, 5)
728 // TODO(fbarchard): Make 1555 neon work same as C code, reduce to diff 9.
729 TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2, 15)
730 TESTATOPLANAR(ARGB4444, 2, 1, I420, 2, 2, 17)
731 TESTATOPLANAR(ARGB, 4, 1, I411, 4, 1, 4)
732 TESTATOPLANAR(ARGB, 4, 1, I422, 2, 1, 2)
733 TESTATOPLANAR(ARGB, 4, 1, I444, 1, 1, 2)
734 TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2, 2)
735 TESTATOPLANAR(UYVY, 2, 1, I420, 2, 2, 2)
736 TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1, 2)
737 TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1, 2)
738 TESTATOPLANAR(I400, 1, 1, I420, 2, 2, 2)
739 TESTATOPLANAR(BayerBGGR, 1, 2, I420, 2, 2, 4)
740 TESTATOPLANAR(BayerRGGB, 1, 2, I420, 2, 2, 4)
741 TESTATOPLANAR(BayerGBRG, 1, 2, I420, 2, 2, 4)
742 TESTATOPLANAR(BayerGRBG, 1, 2, I420, 2, 2, 4)
743
744 #define TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,       \
745                        W1280, N, NEG, OFF)                                     \
746 TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) {                                 \
747   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
748   const int kHeight = benchmark_height_;                                       \
749   const int kStride = (kWidth * 8 * BPP_A + 7) / 8;                            \
750   align_buffer_64(src_argb, kStride * kHeight + OFF);                          \
751   align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
752   align_buffer_64(dst_uv_c,                                                    \
753                   SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                           \
754                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
755   align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
756   align_buffer_64(dst_uv_opt,                                                  \
757                   SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                           \
758                   SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
759   srandom(time(NULL));                                                         \
760   for (int i = 0; i < kHeight; ++i)                                            \
761     for (int j = 0; j < kStride; ++j)                                          \
762       src_argb[(i * kStride) + j + OFF] = (random() & 0xff);                   \
763   memset(dst_y_c, 1, kWidth * kHeight);                                        \
764   memset(dst_uv_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                       \
765                       SUBSAMPLE(kHeight, SUBSAMP_Y));                          \
766   memset(dst_y_opt, 101, kWidth * kHeight);                                    \
767   memset(dst_uv_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                   \
768                         SUBSAMPLE(kHeight, SUBSAMP_Y));                        \
769   MaskCpuFlags(0);                                                             \
770   FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                               \
771                         dst_y_c, kWidth,                                       \
772                         dst_uv_c, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,            \
773                         kWidth, NEG kHeight);                                  \
774   MaskCpuFlags(-1);                                                            \
775   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
776     FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                             \
777                           dst_y_opt, kWidth,                                   \
778                           dst_uv_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,        \
779                           kWidth, NEG kHeight);                                \
780   }                                                                            \
781   int max_diff = 0;                                                            \
782   for (int i = 0; i < kHeight; ++i) {                                          \
783     for (int j = 0; j < kWidth; ++j) {                                         \
784       int abs_diff =                                                           \
785           abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
786               static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
787       if (abs_diff > max_diff) {                                               \
788         max_diff = abs_diff;                                                   \
789       }                                                                        \
790     }                                                                          \
791   }                                                                            \
792   EXPECT_LE(max_diff, 4);                                                      \
793   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
794     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) {               \
795       int abs_diff =                                                           \
796           abs(static_cast<int>(dst_uv_c[i *                                    \
797                                SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]) -        \
798               static_cast<int>(dst_uv_opt[i *                                  \
799                                SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]));        \
800       if (abs_diff > max_diff) {                                               \
801         max_diff = abs_diff;                                                   \
802       }                                                                        \
803     }                                                                          \
804   }                                                                            \
805   EXPECT_LE(max_diff, 4);                                                      \
806   free_aligned_buffer_64(dst_y_c);                                             \
807   free_aligned_buffer_64(dst_uv_c);                                            \
808   free_aligned_buffer_64(dst_y_opt);                                           \
809   free_aligned_buffer_64(dst_uv_opt);                                          \
810   free_aligned_buffer_64(src_argb);                                            \
811 }
812
813 #define TESTATOBIPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)        \
814     TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
815                      benchmark_width_ - 4, _Any, +, 0)                         \
816     TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
817                      benchmark_width_, _Unaligned, +, 1)                       \
818     TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
819                      benchmark_width_, _Invert, -, 0)                          \
820     TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
821                      benchmark_width_, _Opt, +, 0)
822
823 TESTATOBIPLANAR(ARGB, 4, NV12, 2, 2)
824 TESTATOBIPLANAR(ARGB, 4, NV21, 2, 2)
825
826 #define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                            \
827                   FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                            \
828                   W1280, DIFF, N, NEG, OFF)                                    \
829 TEST_F(libyuvTest, FMT_A##To##FMT_B##N) {                                      \
830   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
831   const int kHeight = benchmark_height_;                                       \
832   const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A;         \
833   const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B;         \
834   const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;  \
835   const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;  \
836   align_buffer_64(src_argb, kStrideA * kHeightA + OFF);                        \
837   align_buffer_64(dst_argb_c, kStrideB * kHeightB);                            \
838   align_buffer_64(dst_argb_opt, kStrideB * kHeightB);                          \
839   srandom(time(NULL));                                                         \
840   for (int i = 0; i < kStrideA * kHeightA; ++i) {                              \
841     src_argb[i + OFF] = (random() & 0xff);                                     \
842   }                                                                            \
843   memset(dst_argb_c, 1, kStrideB * kHeightB);                                  \
844   memset(dst_argb_opt, 101, kStrideB * kHeightB);                              \
845   MaskCpuFlags(0);                                                             \
846   FMT_A##To##FMT_B(src_argb + OFF, kStrideA,                                   \
847                    dst_argb_c, kStrideB,                                       \
848                    kWidth, NEG kHeight);                                       \
849   MaskCpuFlags(-1);                                                            \
850   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
851     FMT_A##To##FMT_B(src_argb + OFF, kStrideA,                                 \
852                      dst_argb_opt, kStrideB,                                   \
853                      kWidth, NEG kHeight);                                     \
854   }                                                                            \
855   int max_diff = 0;                                                            \
856   for (int i = 0; i < kStrideB * kHeightB; ++i) {                              \
857     int abs_diff =                                                             \
858         abs(static_cast<int>(dst_argb_c[i]) -                                  \
859             static_cast<int>(dst_argb_opt[i]));                                \
860     if (abs_diff > max_diff) {                                                 \
861       max_diff = abs_diff;                                                     \
862     }                                                                          \
863   }                                                                            \
864   EXPECT_LE(max_diff, DIFF);                                                   \
865   free_aligned_buffer_64(src_argb);                                            \
866   free_aligned_buffer_64(dst_argb_c);                                          \
867   free_aligned_buffer_64(dst_argb_opt);                                        \
868 }
869
870 #define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                       \
871                        FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF)                 \
872 TEST_F(libyuvTest, FMT_A##To##FMT_B##_Random) {                                \
873   srandom(time(NULL));                                                         \
874   for (int times = 0; times < benchmark_iterations_; ++times) {                \
875     const int kWidth = (random() & 63) + 1;                                    \
876     const int kHeight = (random() & 31) + 1;                                   \
877     const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A;       \
878     const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B;       \
879     const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;\
880     const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;\
881     align_buffer_page_end(src_argb, kStrideA * kHeightA);                      \
882     align_buffer_page_end(dst_argb_c, kStrideB * kHeightB);                    \
883     align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB);                  \
884     for (int i = 0; i < kStrideA * kHeightA; ++i) {                            \
885       src_argb[i] = (random() & 0xff);                                         \
886     }                                                                          \
887     memset(dst_argb_c, 123, kStrideB * kHeightB);                              \
888     memset(dst_argb_opt, 123, kStrideB * kHeightB);                            \
889     MaskCpuFlags(0);                                                           \
890     FMT_A##To##FMT_B(src_argb, kStrideA,                                       \
891                      dst_argb_c, kStrideB,                                     \
892                      kWidth, kHeight);                                         \
893     MaskCpuFlags(-1);                                                          \
894     FMT_A##To##FMT_B(src_argb, kStrideA,                                       \
895                      dst_argb_opt, kStrideB,                                   \
896                      kWidth, kHeight);                                         \
897     int max_diff = 0;                                                          \
898     for (int i = 0; i < kStrideB * kHeightB; ++i) {                            \
899       int abs_diff =                                                           \
900           abs(static_cast<int>(dst_argb_c[i]) -                                \
901               static_cast<int>(dst_argb_opt[i]));                              \
902       if (abs_diff > max_diff) {                                               \
903         max_diff = abs_diff;                                                   \
904       }                                                                        \
905     }                                                                          \
906     EXPECT_LE(max_diff, DIFF);                                                 \
907     free_aligned_buffer_page_end(src_argb);                                    \
908     free_aligned_buffer_page_end(dst_argb_c);                                  \
909     free_aligned_buffer_page_end(dst_argb_opt);                                \
910   }                                                                            \
911 }
912
913 #define TESTATOB(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                             \
914                  FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF)                       \
915     TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
916               FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
917               benchmark_width_ - 4, DIFF, _Any, +, 0)                          \
918     TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
919               FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
920               benchmark_width_, DIFF, _Unaligned, +, 1)                        \
921     TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
922               FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
923               benchmark_width_, DIFF, _Invert, -, 0)                           \
924     TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
925               FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
926               benchmark_width_, DIFF, _Opt, +, 0)                              \
927     TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                           \
928                    FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF)
929
930 TESTATOB(ARGB, 4, 4, 1, ARGB, 4, 4, 1, 0)
931 TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0)
932 TESTATOB(ARGB, 4, 4, 1, ABGR, 4, 4, 1, 0)
933 TESTATOB(ARGB, 4, 4, 1, RGBA, 4, 4, 1, 0)
934 TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0)
935 TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0)
936 TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0)
937 TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0)
938 TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0)
939 TESTATOB(ARGB, 4, 4, 1, BayerBGGR, 1, 1, 1, 0)
940 TESTATOB(ARGB, 4, 4, 1, BayerRGGB, 1, 1, 1, 0)
941 TESTATOB(ARGB, 4, 4, 1, BayerGBRG, 1, 1, 1, 0)
942 TESTATOB(ARGB, 4, 4, 1, BayerGRBG, 1, 1, 1, 0)
943 TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4)
944 TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4)
945 TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2)
946 TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2)
947 TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0)
948 TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0)
949 TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0)
950 TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1, 0)
951 TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1, 0)
952 TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0)
953 TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0)
954 TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0)
955 TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, 4)
956 TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, 4)
957 TESTATOB(BayerBGGR, 1, 2, 2, ARGB, 4, 4, 1, 0)
958 TESTATOB(BayerRGGB, 1, 2, 2, ARGB, 4, 4, 1, 0)
959 TESTATOB(BayerGBRG, 1, 2, 2, ARGB, 4, 4, 1, 0)
960 TESTATOB(BayerGRBG, 1, 2, 2, ARGB, 4, 4, 1, 0)
961 TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0)
962 TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1, 0)
963 TESTATOB(I400, 1, 1, 1, I400Mirror, 1, 1, 1, 0)
964 TESTATOB(Y, 1, 1, 1, ARGB, 4, 4, 1, 0)
965 TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0)
966
967 #define TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A,                          \
968                  W1280, N, NEG, OFF)                                           \
969 TEST_F(libyuvTest, FMT_ATOB##_Symetric##N) {                                   \
970   const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
971   const int kHeight = benchmark_height_;                                       \
972   const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A;         \
973   const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;  \
974   align_buffer_64(src_argb, kStrideA * kHeightA + OFF);                        \
975   align_buffer_64(dst_argb_c, kStrideA * kHeightA);                            \
976   align_buffer_64(dst_argb_opt, kStrideA * kHeightA);                          \
977   srandom(time(NULL));                                                         \
978   for (int i = 0; i < kStrideA * kHeightA; ++i) {                              \
979     src_argb[i + OFF] = (random() & 0xff);                                     \
980   }                                                                            \
981   memset(dst_argb_c, 1, kStrideA * kHeightA);                                  \
982   memset(dst_argb_opt, 101, kStrideA * kHeightA);                              \
983   MaskCpuFlags(0);                                                             \
984   FMT_ATOB(src_argb + OFF, kStrideA,                                           \
985            dst_argb_c, kStrideA,                                               \
986            kWidth, NEG kHeight);                                               \
987   MaskCpuFlags(-1);                                                            \
988   for (int i = 0; i < benchmark_iterations_; ++i) {                            \
989     FMT_ATOB(src_argb + OFF, kStrideA,                                         \
990              dst_argb_opt, kStrideA,                                           \
991              kWidth, NEG kHeight);                                             \
992   }                                                                            \
993   MaskCpuFlags(0);                                                             \
994   FMT_ATOB(dst_argb_c, kStrideA,                                               \
995            dst_argb_c, kStrideA,                                               \
996            kWidth, NEG kHeight);                                               \
997   MaskCpuFlags(-1);                                                            \
998   FMT_ATOB(dst_argb_opt, kStrideA,                                             \
999            dst_argb_opt, kStrideA,                                             \
1000            kWidth, NEG kHeight);                                               \
1001   for (int i = 0; i < kStrideA * kHeightA; ++i) {                              \
1002     EXPECT_EQ(src_argb[i + OFF], dst_argb_opt[i]);                             \
1003     EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]);                                 \
1004   }                                                                            \
1005   free_aligned_buffer_64(src_argb);                                            \
1006   free_aligned_buffer_64(dst_argb_c);                                          \
1007   free_aligned_buffer_64(dst_argb_opt);                                        \
1008 }
1009
1010 #define TESTSYM(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A)                           \
1011     TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A,                              \
1012              benchmark_width_ - 4, _Any, +, 0)                                 \
1013     TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A,                              \
1014              benchmark_width_, _Unaligned, +, 1)                               \
1015     TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A,                              \
1016              benchmark_width_, _Opt, +, 0)
1017
1018 TESTSYM(ARGBToARGB, 4, 4, 1)
1019 TESTSYM(ARGBToBGRA, 4, 4, 1)
1020 TESTSYM(ARGBToABGR, 4, 4, 1)
1021 TESTSYM(BGRAToARGB, 4, 4, 1)
1022 TESTSYM(ABGRToARGB, 4, 4, 1)
1023
1024 TEST_F(libyuvTest, Test565) {
1025   SIMD_ALIGNED(uint8 orig_pixels[256][4]);
1026   SIMD_ALIGNED(uint8 pixels565[256][2]);
1027
1028   for (int i = 0; i < 256; ++i) {
1029     for (int j = 0; j < 4; ++j) {
1030       orig_pixels[i][j] = i;
1031     }
1032   }
1033   ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1);
1034   uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381);
1035   EXPECT_EQ(610919429u, checksum);
1036 }
1037
1038 #ifdef HAVE_JPEG
1039 TEST_F(libyuvTest, ValidateJpeg) {
1040   const int kOff = 10;
1041   const int kMinJpeg = 64;
1042   const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
1043     benchmark_width_ * benchmark_height_ : kMinJpeg;
1044   const int kSize = kImageSize + kOff;
1045   align_buffer_64(orig_pixels, kSize);
1046
1047   // No SOI or EOI. Expect fail.
1048   memset(orig_pixels, 0, kSize);
1049   EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
1050
1051   // EOI, SOI. Expect pass.
1052   orig_pixels[0] = 0xff;
1053   orig_pixels[1] = 0xd8;  // SOI.
1054   orig_pixels[kSize - kOff + 0] = 0xff;
1055   orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
1056   for (int times = 0; times < benchmark_iterations_; ++times) {
1057     EXPECT_TRUE(ValidateJpeg(orig_pixels, kSize));
1058   }
1059   free_aligned_buffer_page_end(orig_pixels);
1060 }
1061
1062 TEST_F(libyuvTest, InvalidateJpeg) {
1063   const int kOff = 10;
1064   const int kMinJpeg = 64;
1065   const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
1066     benchmark_width_ * benchmark_height_ : kMinJpeg;
1067   const int kSize = kImageSize + kOff;
1068   align_buffer_64(orig_pixels, kSize);
1069
1070   // No SOI or EOI. Expect fail.
1071   memset(orig_pixels, 0, kSize);
1072   EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
1073
1074   // SOI but no EOI. Expect fail.
1075   orig_pixels[0] = 0xff;
1076   orig_pixels[1] = 0xd8;  // SOI.
1077   for (int times = 0; times < benchmark_iterations_; ++times) {
1078     EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
1079   }
1080   // EOI but no SOI. Expect fail.
1081   orig_pixels[0] = 0;
1082   orig_pixels[1] = 0;
1083   orig_pixels[kSize - kOff + 0] = 0xff;
1084   orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
1085   EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
1086
1087   free_aligned_buffer_page_end(orig_pixels);
1088 }
1089
1090 TEST_F(libyuvTest, MJPGToI420) {
1091   const int kOff = 10;
1092   const int kMinJpeg = 64;
1093   const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
1094     benchmark_width_ * benchmark_height_ : kMinJpeg;
1095   const int kSize = kImageSize + kOff;
1096   align_buffer_64(orig_pixels, kSize);
1097   align_buffer_64(dst_y_opt, benchmark_width_ * benchmark_height_);
1098   align_buffer_64(dst_u_opt,
1099                   SUBSAMPLE(benchmark_width_, 2) *
1100                   SUBSAMPLE(benchmark_height_, 2));
1101   align_buffer_64(dst_v_opt,
1102                   SUBSAMPLE(benchmark_width_, 2) *
1103                   SUBSAMPLE(benchmark_height_, 2));
1104
1105   // EOI, SOI to make MJPG appear valid.
1106   memset(orig_pixels, 0, kSize);
1107   orig_pixels[0] = 0xff;
1108   orig_pixels[1] = 0xd8;  // SOI.
1109   orig_pixels[kSize - kOff + 0] = 0xff;
1110   orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
1111
1112   for (int times = 0; times < benchmark_iterations_; ++times) {
1113     int ret = MJPGToI420(orig_pixels, kSize,
1114                          dst_y_opt, benchmark_width_,
1115                          dst_u_opt, SUBSAMPLE(benchmark_width_, 2),
1116                          dst_v_opt, SUBSAMPLE(benchmark_width_, 2),
1117                          benchmark_width_, benchmark_height_,
1118                          benchmark_width_, benchmark_height_);
1119     // Expect failure because image is not really valid.
1120     EXPECT_EQ(1, ret);
1121   }
1122
1123   free_aligned_buffer_page_end(dst_y_opt);
1124   free_aligned_buffer_page_end(dst_u_opt);
1125   free_aligned_buffer_page_end(dst_v_opt);
1126   free_aligned_buffer_page_end(orig_pixels);
1127 }
1128
1129 TEST_F(libyuvTest, MJPGToARGB) {
1130   const int kOff = 10;
1131   const int kMinJpeg = 64;
1132   const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
1133     benchmark_width_ * benchmark_height_ : kMinJpeg;
1134   const int kSize = kImageSize + kOff;
1135   align_buffer_64(orig_pixels, kSize);
1136   align_buffer_64(dst_argb_opt, benchmark_width_ * benchmark_height_ * 4);
1137
1138   // EOI, SOI to make MJPG appear valid.
1139   memset(orig_pixels, 0, kSize);
1140   orig_pixels[0] = 0xff;
1141   orig_pixels[1] = 0xd8;  // SOI.
1142   orig_pixels[kSize - kOff + 0] = 0xff;
1143   orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
1144
1145   for (int times = 0; times < benchmark_iterations_; ++times) {
1146     int ret = MJPGToARGB(orig_pixels, kSize,
1147                          dst_argb_opt, benchmark_width_ * 4,
1148                          benchmark_width_, benchmark_height_,
1149                          benchmark_width_, benchmark_height_);
1150     // Expect failure because image is not really valid.
1151     EXPECT_EQ(1, ret);
1152   }
1153
1154   free_aligned_buffer_page_end(dst_argb_opt);
1155   free_aligned_buffer_page_end(orig_pixels);
1156 }
1157
1158 #endif  // HAVE_JPEG
1159
1160 TEST_F(libyuvTest, CropNV12) {
1161   const int SUBSAMP_X = 2;
1162   const int SUBSAMP_Y = 2;
1163   const int kWidth = benchmark_width_;
1164   const int kHeight = benchmark_height_;
1165   const int crop_y =
1166     (benchmark_height_ - (benchmark_height_ * 360 / 480)) / 2;
1167   const int kDestWidth = benchmark_width_;
1168   const int kDestHeight = benchmark_height_ - crop_y * 2;;
1169   const int sample_size = kWidth * kHeight +
1170     SUBSAMPLE(kWidth, SUBSAMP_X) *
1171     SUBSAMPLE(kHeight, SUBSAMP_Y) * 2;
1172   align_buffer_64(src_y, sample_size);
1173   uint8* src_uv = src_y + kWidth * kHeight;
1174
1175   align_buffer_64(dst_y, kDestWidth * kDestHeight);
1176   align_buffer_64(dst_u,
1177                   SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1178                   SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1179   align_buffer_64(dst_v,
1180                   SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1181                   SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1182
1183   align_buffer_64(dst_y_2, kDestWidth * kDestHeight);
1184   align_buffer_64(dst_u_2,
1185                   SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1186                   SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1187   align_buffer_64(dst_v_2,
1188                   SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1189                   SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1190
1191   srandom(time(NULL));
1192   for (int i = 0; i < kHeight; ++i)
1193     for (int j = 0; j < kWidth; ++j)
1194       src_y[(i * kWidth) + j] = (random() & 0xff);
1195   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {
1196     for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {
1197       src_uv[(i * SUBSAMPLE(kWidth, SUBSAMP_X)) + j * 2 + 0] =
1198           (random() & 0xff);
1199       src_uv[(i * SUBSAMPLE(kWidth, SUBSAMP_X)) + j * 2 + 1] =
1200           (random() & 0xff);
1201     }
1202   }
1203   memset(dst_y, 1, kDestWidth * kDestHeight);
1204   memset(dst_u, 2, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1205                    SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1206   memset(dst_v, 3, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1207                    SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1208   memset(dst_y_2, 1, kDestWidth * kDestHeight);
1209   memset(dst_u_2, 2, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1210                      SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1211   memset(dst_v_2, 3, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1212                      SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1213
1214   NV12ToI420(src_y + crop_y * kWidth, kWidth,
1215              src_uv + (crop_y / 2) * kWidth, kWidth,
1216              dst_y, kDestWidth,
1217              dst_u, SUBSAMPLE(kDestWidth, SUBSAMP_X),
1218              dst_v, SUBSAMPLE(kDestWidth, SUBSAMP_X),
1219              kDestWidth, kDestHeight);
1220
1221   ConvertToI420(src_y, sample_size,
1222                 dst_y_2, kDestWidth,
1223                 dst_u_2, SUBSAMPLE(kDestWidth, SUBSAMP_X),
1224                 dst_v_2, SUBSAMPLE(kDestWidth, SUBSAMP_X),
1225                 0, crop_y,
1226                 kWidth, kHeight,
1227                 kDestWidth, kDestHeight,
1228                 libyuv::kRotate0, libyuv::FOURCC_NV12);
1229
1230   for (int i = 0; i < kDestHeight; ++i) {
1231     for (int j = 0; j < kDestWidth; ++j) {
1232       EXPECT_EQ(dst_y[i * kWidth + j], dst_y_2[i * kWidth + j]);
1233     }
1234   }
1235   for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
1236     for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
1237       EXPECT_EQ(dst_u[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j],
1238                 dst_u_2[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
1239     }
1240   }
1241   for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
1242     for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
1243       EXPECT_EQ(dst_v[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j],
1244                 dst_v_2[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
1245     }
1246   }
1247   free_aligned_buffer_64(dst_y);
1248   free_aligned_buffer_64(dst_u);
1249   free_aligned_buffer_64(dst_v);
1250   free_aligned_buffer_64(dst_y_2);
1251   free_aligned_buffer_64(dst_u_2);
1252   free_aligned_buffer_64(dst_v_2);
1253   free_aligned_buffer_64(src_y);
1254 }
1255
1256 TEST_F(libyuvTest, HaveJPEG) {
1257 #ifdef HAVE_JPEG
1258   printf("JPEG enabled\n.");
1259 #else
1260   printf("JPEG disabled\n.");
1261 #endif
1262 }
1263
1264 }  // namespace libyuv