xref: /aosp_15_r20/external/libyuv/unit_test/convert_test.cc (revision 4e366538070a3a6c5c163c31b791eab742e1657a)
1*4e366538SXin Li /*
2*4e366538SXin Li  *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
3*4e366538SXin Li  *
4*4e366538SXin Li  *  Use of this source code is governed by a BSD-style license
5*4e366538SXin Li  *  that can be found in the LICENSE file in the root of the source
6*4e366538SXin Li  *  tree. An additional intellectual property rights grant can be found
7*4e366538SXin Li  *  in the file PATENTS. All contributing project authors may
8*4e366538SXin Li  *  be found in the AUTHORS file in the root of the source tree.
9*4e366538SXin Li  */
10*4e366538SXin Li 
11*4e366538SXin Li #include <assert.h>
12*4e366538SXin Li #include <stdlib.h>
13*4e366538SXin Li #include <time.h>
14*4e366538SXin Li 
15*4e366538SXin Li #include "libyuv/basic_types.h"
16*4e366538SXin Li #include "libyuv/compare.h"
17*4e366538SXin Li #include "libyuv/convert.h"
18*4e366538SXin Li #include "libyuv/convert_argb.h"
19*4e366538SXin Li #include "libyuv/convert_from.h"
20*4e366538SXin Li #include "libyuv/convert_from_argb.h"
21*4e366538SXin Li #include "libyuv/cpu_id.h"
22*4e366538SXin Li #ifdef HAVE_JPEG
23*4e366538SXin Li #include "libyuv/mjpeg_decoder.h"
24*4e366538SXin Li #endif
25*4e366538SXin Li #include "../unit_test/unit_test.h"
26*4e366538SXin Li #include "libyuv/planar_functions.h"
27*4e366538SXin Li #include "libyuv/rotate.h"
28*4e366538SXin Li #include "libyuv/video_common.h"
29*4e366538SXin Li 
30*4e366538SXin Li #ifdef ENABLE_ROW_TESTS
31*4e366538SXin Li #include "libyuv/row.h" /* For ARGBToAR30Row_AVX2 */
32*4e366538SXin Li #endif
33*4e366538SXin Li 
34*4e366538SXin Li #if defined(__riscv) && !defined(__clang__)
35*4e366538SXin Li #define DISABLE_SLOW_TESTS
36*4e366538SXin Li #undef ENABLE_FULL_TESTS
37*4e366538SXin Li #undef ENABLE_ROW_TESTS
38*4e366538SXin Li #define LEAN_TESTS
39*4e366538SXin Li #endif
40*4e366538SXin Li 
41*4e366538SXin Li // Some functions fail on big endian. Enable these tests on all cpus except
42*4e366538SXin Li // PowerPC, but they are not optimized so disabled by default.
43*4e366538SXin Li #if !defined(DISABLE_SLOW_TESTS) && !defined(__powerpc__)
44*4e366538SXin Li #define LITTLE_ENDIAN_ONLY_TEST 1
45*4e366538SXin Li #endif
46*4e366538SXin Li #if !defined(DISABLE_SLOW_TESTS) || defined(__x86_64__) || defined(__i386__)
47*4e366538SXin Li // SLOW TESTS are those that are unoptimized C code.
48*4e366538SXin Li // FULL TESTS are optimized but test many variations of the same code.
49*4e366538SXin Li #define ENABLE_FULL_TESTS
50*4e366538SXin Li #endif
51*4e366538SXin Li 
52*4e366538SXin Li namespace libyuv {
53*4e366538SXin Li 
54*4e366538SXin Li // Alias to copy pixels as is
55*4e366538SXin Li #define AR30ToAR30 ARGBCopy
56*4e366538SXin Li #define ABGRToABGR ARGBCopy
57*4e366538SXin Li 
58*4e366538SXin Li // subsample amount uses a divide.
59*4e366538SXin Li #define SUBSAMPLE(v, a) ((((v) + (a)-1)) / (a))
60*4e366538SXin Li 
61*4e366538SXin Li #define ALIGNINT(V, ALIGN) (((V) + (ALIGN)-1) / (ALIGN) * (ALIGN))
62*4e366538SXin Li 
63*4e366538SXin Li // Planar test
64*4e366538SXin Li 
65*4e366538SXin Li #define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,         \
66*4e366538SXin Li                        SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC,             \
67*4e366538SXin Li                        DST_SUBSAMP_X, DST_SUBSAMP_Y, W1280, N, NEG, OFF,      \
68*4e366538SXin Li                        SRC_DEPTH)                                             \
69*4e366538SXin Li   TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {              \
70*4e366538SXin Li     static_assert(SRC_BPC == 1 || SRC_BPC == 2, "SRC BPC unsupported");       \
71*4e366538SXin Li     static_assert(DST_BPC == 1 || DST_BPC == 2, "DST BPC unsupported");       \
72*4e366538SXin Li     static_assert(SRC_SUBSAMP_X == 1 || SRC_SUBSAMP_X == 2,                   \
73*4e366538SXin Li                   "SRC_SUBSAMP_X unsupported");                               \
74*4e366538SXin Li     static_assert(SRC_SUBSAMP_Y == 1 || SRC_SUBSAMP_Y == 2,                   \
75*4e366538SXin Li                   "SRC_SUBSAMP_Y unsupported");                               \
76*4e366538SXin Li     static_assert(DST_SUBSAMP_X == 1 || DST_SUBSAMP_X == 2,                   \
77*4e366538SXin Li                   "DST_SUBSAMP_X unsupported");                               \
78*4e366538SXin Li     static_assert(DST_SUBSAMP_Y == 1 || DST_SUBSAMP_Y == 2,                   \
79*4e366538SXin Li                   "DST_SUBSAMP_Y unsupported");                               \
80*4e366538SXin Li     const int kWidth = W1280;                                                 \
81*4e366538SXin Li     const int kHeight = benchmark_height_;                                    \
82*4e366538SXin Li     const int kSrcHalfWidth = SUBSAMPLE(kWidth, SRC_SUBSAMP_X);               \
83*4e366538SXin Li     const int kSrcHalfHeight = SUBSAMPLE(kHeight, SRC_SUBSAMP_Y);             \
84*4e366538SXin Li     const int kDstHalfWidth = SUBSAMPLE(kWidth, DST_SUBSAMP_X);               \
85*4e366538SXin Li     const int kDstHalfHeight = SUBSAMPLE(kHeight, DST_SUBSAMP_Y);             \
86*4e366538SXin Li     align_buffer_page_end(src_y, kWidth* kHeight* SRC_BPC + OFF);             \
87*4e366538SXin Li     align_buffer_page_end(src_u,                                              \
88*4e366538SXin Li                           kSrcHalfWidth* kSrcHalfHeight* SRC_BPC + OFF);      \
89*4e366538SXin Li     align_buffer_page_end(src_v,                                              \
90*4e366538SXin Li                           kSrcHalfWidth* kSrcHalfHeight* SRC_BPC + OFF);      \
91*4e366538SXin Li     align_buffer_page_end(dst_y_c, kWidth* kHeight* DST_BPC);                 \
92*4e366538SXin Li     align_buffer_page_end(dst_u_c, kDstHalfWidth* kDstHalfHeight* DST_BPC);   \
93*4e366538SXin Li     align_buffer_page_end(dst_v_c, kDstHalfWidth* kDstHalfHeight* DST_BPC);   \
94*4e366538SXin Li     align_buffer_page_end(dst_y_opt, kWidth* kHeight* DST_BPC);               \
95*4e366538SXin Li     align_buffer_page_end(dst_u_opt, kDstHalfWidth* kDstHalfHeight* DST_BPC); \
96*4e366538SXin Li     align_buffer_page_end(dst_v_opt, kDstHalfWidth* kDstHalfHeight* DST_BPC); \
97*4e366538SXin Li     MemRandomize(src_y + OFF, kWidth * kHeight * SRC_BPC);                    \
98*4e366538SXin Li     MemRandomize(src_u + OFF, kSrcHalfWidth * kSrcHalfHeight * SRC_BPC);      \
99*4e366538SXin Li     MemRandomize(src_v + OFF, kSrcHalfWidth * kSrcHalfHeight * SRC_BPC);      \
100*4e366538SXin Li     SRC_T* src_y_p = reinterpret_cast<SRC_T*>(src_y + OFF);                   \
101*4e366538SXin Li     SRC_T* src_u_p = reinterpret_cast<SRC_T*>(src_u + OFF);                   \
102*4e366538SXin Li     SRC_T* src_v_p = reinterpret_cast<SRC_T*>(src_v + OFF);                   \
103*4e366538SXin Li     for (int i = 0; i < kWidth * kHeight; ++i) {                              \
104*4e366538SXin Li       src_y_p[i] = src_y_p[i] & ((1 << SRC_DEPTH) - 1);                       \
105*4e366538SXin Li     }                                                                         \
106*4e366538SXin Li     for (int i = 0; i < kSrcHalfWidth * kSrcHalfHeight; ++i) {                \
107*4e366538SXin Li       src_u_p[i] = src_u_p[i] & ((1 << SRC_DEPTH) - 1);                       \
108*4e366538SXin Li       src_v_p[i] = src_v_p[i] & ((1 << SRC_DEPTH) - 1);                       \
109*4e366538SXin Li     }                                                                         \
110*4e366538SXin Li     memset(dst_y_c, 1, kWidth* kHeight* DST_BPC);                             \
111*4e366538SXin Li     memset(dst_u_c, 2, kDstHalfWidth* kDstHalfHeight* DST_BPC);               \
112*4e366538SXin Li     memset(dst_v_c, 3, kDstHalfWidth* kDstHalfHeight* DST_BPC);               \
113*4e366538SXin Li     memset(dst_y_opt, 101, kWidth* kHeight* DST_BPC);                         \
114*4e366538SXin Li     memset(dst_u_opt, 102, kDstHalfWidth* kDstHalfHeight* DST_BPC);           \
115*4e366538SXin Li     memset(dst_v_opt, 103, kDstHalfWidth* kDstHalfHeight* DST_BPC);           \
116*4e366538SXin Li     MaskCpuFlags(disable_cpu_flags_);                                         \
117*4e366538SXin Li     SRC_FMT_PLANAR##To##FMT_PLANAR(                                           \
118*4e366538SXin Li         src_y_p, kWidth, src_u_p, kSrcHalfWidth, src_v_p, kSrcHalfWidth,      \
119*4e366538SXin Li         reinterpret_cast<DST_T*>(dst_y_c), kWidth,                            \
120*4e366538SXin Li         reinterpret_cast<DST_T*>(dst_u_c), kDstHalfWidth,                     \
121*4e366538SXin Li         reinterpret_cast<DST_T*>(dst_v_c), kDstHalfWidth, kWidth,             \
122*4e366538SXin Li         NEG kHeight);                                                         \
123*4e366538SXin Li     MaskCpuFlags(benchmark_cpu_info_);                                        \
124*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                         \
125*4e366538SXin Li       SRC_FMT_PLANAR##To##FMT_PLANAR(                                         \
126*4e366538SXin Li           src_y_p, kWidth, src_u_p, kSrcHalfWidth, src_v_p, kSrcHalfWidth,    \
127*4e366538SXin Li           reinterpret_cast<DST_T*>(dst_y_opt), kWidth,                        \
128*4e366538SXin Li           reinterpret_cast<DST_T*>(dst_u_opt), kDstHalfWidth,                 \
129*4e366538SXin Li           reinterpret_cast<DST_T*>(dst_v_opt), kDstHalfWidth, kWidth,         \
130*4e366538SXin Li           NEG kHeight);                                                       \
131*4e366538SXin Li     }                                                                         \
132*4e366538SXin Li     for (int i = 0; i < kHeight * kWidth * DST_BPC; ++i) {                    \
133*4e366538SXin Li       EXPECT_EQ(dst_y_c[i], dst_y_opt[i]);                                    \
134*4e366538SXin Li     }                                                                         \
135*4e366538SXin Li     for (int i = 0; i < kDstHalfWidth * kDstHalfHeight * DST_BPC; ++i) {      \
136*4e366538SXin Li       EXPECT_EQ(dst_u_c[i], dst_u_opt[i]);                                    \
137*4e366538SXin Li       EXPECT_EQ(dst_v_c[i], dst_v_opt[i]);                                    \
138*4e366538SXin Li     }                                                                         \
139*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_c);                                    \
140*4e366538SXin Li     free_aligned_buffer_page_end(dst_u_c);                                    \
141*4e366538SXin Li     free_aligned_buffer_page_end(dst_v_c);                                    \
142*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_opt);                                  \
143*4e366538SXin Li     free_aligned_buffer_page_end(dst_u_opt);                                  \
144*4e366538SXin Li     free_aligned_buffer_page_end(dst_v_opt);                                  \
145*4e366538SXin Li     free_aligned_buffer_page_end(src_y);                                      \
146*4e366538SXin Li     free_aligned_buffer_page_end(src_u);                                      \
147*4e366538SXin Li     free_aligned_buffer_page_end(src_v);                                      \
148*4e366538SXin Li   }
149*4e366538SXin Li 
150*4e366538SXin Li #if defined(ENABLE_FULL_TESTS)
151*4e366538SXin Li #define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,           \
152*4e366538SXin Li                       SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC,               \
153*4e366538SXin Li                       DST_SUBSAMP_X, DST_SUBSAMP_Y, SRC_DEPTH)                 \
154*4e366538SXin Li   TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
155*4e366538SXin Li                  FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,     \
156*4e366538SXin Li                  benchmark_width_ + 1, _Any, +, 0, SRC_DEPTH)                  \
157*4e366538SXin Li   TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
158*4e366538SXin Li                  FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,     \
159*4e366538SXin Li                  benchmark_width_, _Unaligned, +, 2, SRC_DEPTH)                \
160*4e366538SXin Li   TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
161*4e366538SXin Li                  FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,     \
162*4e366538SXin Li                  benchmark_width_, _Invert, -, 0, SRC_DEPTH)                   \
163*4e366538SXin Li   TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
164*4e366538SXin Li                  FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,     \
165*4e366538SXin Li                  benchmark_width_, _Opt, +, 0, SRC_DEPTH)
166*4e366538SXin Li #else
167*4e366538SXin Li #define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,           \
168*4e366538SXin Li                       SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC,               \
169*4e366538SXin Li                       DST_SUBSAMP_X, DST_SUBSAMP_Y, SRC_DEPTH)                 \
170*4e366538SXin Li   TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
171*4e366538SXin Li                  FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,     \
172*4e366538SXin Li                  benchmark_width_, _Opt, +, 0, SRC_DEPTH)
173*4e366538SXin Li #endif
174*4e366538SXin Li 
175*4e366538SXin Li TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I420, uint8_t, 1, 2, 2, 8)
176*4e366538SXin Li TESTPLANARTOP(I422, uint8_t, 1, 2, 1, I420, uint8_t, 1, 2, 2, 8)
177*4e366538SXin Li TESTPLANARTOP(I444, uint8_t, 1, 1, 1, I420, uint8_t, 1, 2, 2, 8)
178*4e366538SXin Li TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I422, uint8_t, 1, 2, 1, 8)
179*4e366538SXin Li TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I444, uint8_t, 1, 1, 1, 8)
180*4e366538SXin Li TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I420Mirror, uint8_t, 1, 2, 2, 8)
181*4e366538SXin Li TESTPLANARTOP(I422, uint8_t, 1, 2, 1, I422, uint8_t, 1, 2, 1, 8)
182*4e366538SXin Li TESTPLANARTOP(I422, uint8_t, 1, 2, 1, I444, uint8_t, 1, 1, 1, 8)
183*4e366538SXin Li TESTPLANARTOP(I444, uint8_t, 1, 1, 1, I444, uint8_t, 1, 1, 1, 8)
184*4e366538SXin Li TESTPLANARTOP(I010, uint16_t, 2, 2, 2, I010, uint16_t, 2, 2, 2, 10)
185*4e366538SXin Li TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I010, uint16_t, 2, 2, 2, 8)
186*4e366538SXin Li TESTPLANARTOP(I420, uint8_t, 1, 2, 2, I012, uint16_t, 2, 2, 2, 8)
187*4e366538SXin Li TESTPLANARTOP(H010, uint16_t, 2, 2, 2, H010, uint16_t, 2, 2, 2, 10)
188*4e366538SXin Li TESTPLANARTOP(H010, uint16_t, 2, 2, 2, H420, uint8_t, 1, 2, 2, 10)
189*4e366538SXin Li TESTPLANARTOP(H420, uint8_t, 1, 2, 2, H010, uint16_t, 2, 2, 2, 8)
190*4e366538SXin Li TESTPLANARTOP(H420, uint8_t, 1, 2, 2, H012, uint16_t, 2, 2, 2, 8)
191*4e366538SXin Li TESTPLANARTOP(I010, uint16_t, 2, 2, 2, I410, uint16_t, 2, 1, 1, 10)
192*4e366538SXin Li TESTPLANARTOP(I210, uint16_t, 2, 2, 1, I410, uint16_t, 2, 1, 1, 10)
193*4e366538SXin Li TESTPLANARTOP(I012, uint16_t, 2, 2, 2, I412, uint16_t, 2, 1, 1, 12)
194*4e366538SXin Li TESTPLANARTOP(I212, uint16_t, 2, 2, 1, I412, uint16_t, 2, 1, 1, 12)
195*4e366538SXin Li TESTPLANARTOP(I410, uint16_t, 2, 1, 1, I010, uint16_t, 2, 2, 2, 10)
196*4e366538SXin Li TESTPLANARTOP(I210, uint16_t, 2, 2, 1, I010, uint16_t, 2, 2, 2, 10)
197*4e366538SXin Li TESTPLANARTOP(I412, uint16_t, 2, 1, 1, I012, uint16_t, 2, 2, 2, 12)
198*4e366538SXin Li TESTPLANARTOP(I212, uint16_t, 2, 2, 1, I012, uint16_t, 2, 2, 2, 12)
199*4e366538SXin Li TESTPLANARTOP(I010, uint16_t, 2, 2, 2, I420, uint8_t, 1, 2, 2, 10)
200*4e366538SXin Li TESTPLANARTOP(I210, uint16_t, 2, 2, 1, I420, uint8_t, 1, 2, 2, 10)
201*4e366538SXin Li TESTPLANARTOP(I210, uint16_t, 2, 2, 1, I422, uint8_t, 1, 2, 1, 10)
202*4e366538SXin Li TESTPLANARTOP(I410, uint16_t, 2, 1, 1, I420, uint8_t, 1, 2, 2, 10)
203*4e366538SXin Li TESTPLANARTOP(I410, uint16_t, 2, 1, 1, I444, uint8_t, 1, 1, 1, 10)
204*4e366538SXin Li TESTPLANARTOP(I012, uint16_t, 2, 2, 2, I420, uint8_t, 1, 2, 2, 12)
205*4e366538SXin Li TESTPLANARTOP(I212, uint16_t, 2, 2, 1, I420, uint8_t, 1, 2, 2, 12)
206*4e366538SXin Li TESTPLANARTOP(I212, uint16_t, 2, 2, 1, I422, uint8_t, 1, 2, 1, 12)
207*4e366538SXin Li TESTPLANARTOP(I412, uint16_t, 2, 1, 1, I420, uint8_t, 1, 2, 2, 12)
208*4e366538SXin Li TESTPLANARTOP(I412, uint16_t, 2, 1, 1, I444, uint8_t, 1, 1, 1, 12)
209*4e366538SXin Li 
210*4e366538SXin Li // Test Android 420 to I420
211*4e366538SXin Li #define TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X,          \
212*4e366538SXin Li                         SRC_SUBSAMP_Y, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
213*4e366538SXin Li                         W1280, N, NEG, OFF, PN, OFF_U, OFF_V)                 \
214*4e366538SXin Li   TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##To##PN##N) {      \
215*4e366538SXin Li     const int kWidth = W1280;                                                 \
216*4e366538SXin Li     const int kHeight = benchmark_height_;                                    \
217*4e366538SXin Li     const int kSizeUV =                                                       \
218*4e366538SXin Li         SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); \
219*4e366538SXin Li     align_buffer_page_end(src_y, kWidth* kHeight + OFF);                      \
220*4e366538SXin Li     align_buffer_page_end(src_uv,                                             \
221*4e366538SXin Li                           kSizeUV*((PIXEL_STRIDE == 3) ? 3 : 2) + OFF);       \
222*4e366538SXin Li     align_buffer_page_end(dst_y_c, kWidth* kHeight);                          \
223*4e366538SXin Li     align_buffer_page_end(dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X) *             \
224*4e366538SXin Li                                        SUBSAMPLE(kHeight, SUBSAMP_Y));        \
225*4e366538SXin Li     align_buffer_page_end(dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X) *             \
226*4e366538SXin Li                                        SUBSAMPLE(kHeight, SUBSAMP_Y));        \
227*4e366538SXin Li     align_buffer_page_end(dst_y_opt, kWidth* kHeight);                        \
228*4e366538SXin Li     align_buffer_page_end(dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X) *           \
229*4e366538SXin Li                                          SUBSAMPLE(kHeight, SUBSAMP_Y));      \
230*4e366538SXin Li     align_buffer_page_end(dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X) *           \
231*4e366538SXin Li                                          SUBSAMPLE(kHeight, SUBSAMP_Y));      \
232*4e366538SXin Li     uint8_t* src_u = src_uv + OFF_U;                                          \
233*4e366538SXin Li     uint8_t* src_v = src_uv + (PIXEL_STRIDE == 1 ? kSizeUV : OFF_V);          \
234*4e366538SXin Li     int src_stride_uv = SUBSAMPLE(kWidth, SUBSAMP_X) * PIXEL_STRIDE;          \
235*4e366538SXin Li     for (int i = 0; i < kHeight; ++i)                                         \
236*4e366538SXin Li       for (int j = 0; j < kWidth; ++j)                                        \
237*4e366538SXin Li         src_y[i * kWidth + j + OFF] = (fastrand() & 0xff);                    \
238*4e366538SXin Li     for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) {             \
239*4e366538SXin Li       for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) {            \
240*4e366538SXin Li         src_u[(i * src_stride_uv) + j * PIXEL_STRIDE + OFF] =                 \
241*4e366538SXin Li             (fastrand() & 0xff);                                              \
242*4e366538SXin Li         src_v[(i * src_stride_uv) + j * PIXEL_STRIDE + OFF] =                 \
243*4e366538SXin Li             (fastrand() & 0xff);                                              \
244*4e366538SXin Li       }                                                                       \
245*4e366538SXin Li     }                                                                         \
246*4e366538SXin Li     memset(dst_y_c, 1, kWidth* kHeight);                                      \
247*4e366538SXin Li     memset(dst_u_c, 2,                                                        \
248*4e366538SXin Li            SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));     \
249*4e366538SXin Li     memset(dst_v_c, 3,                                                        \
250*4e366538SXin Li            SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));     \
251*4e366538SXin Li     memset(dst_y_opt, 101, kWidth* kHeight);                                  \
252*4e366538SXin Li     memset(dst_u_opt, 102,                                                    \
253*4e366538SXin Li            SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));     \
254*4e366538SXin Li     memset(dst_v_opt, 103,                                                    \
255*4e366538SXin Li            SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));     \
256*4e366538SXin Li     MaskCpuFlags(disable_cpu_flags_);                                         \
257*4e366538SXin Li     SRC_FMT_PLANAR##To##FMT_PLANAR(                                           \
258*4e366538SXin Li         src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X),   \
259*4e366538SXin Li         src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), PIXEL_STRIDE, dst_y_c, \
260*4e366538SXin Li         kWidth, dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), dst_v_c,               \
261*4e366538SXin Li         SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight);                   \
262*4e366538SXin Li     MaskCpuFlags(benchmark_cpu_info_);                                        \
263*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                         \
264*4e366538SXin Li       SRC_FMT_PLANAR##To##FMT_PLANAR(                                         \
265*4e366538SXin Li           src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
266*4e366538SXin Li           src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), PIXEL_STRIDE,        \
267*4e366538SXin Li           dst_y_opt, kWidth, dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X),         \
268*4e366538SXin Li           dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight);      \
269*4e366538SXin Li     }                                                                         \
270*4e366538SXin Li     for (int i = 0; i < kHeight; ++i) {                                       \
271*4e366538SXin Li       for (int j = 0; j < kWidth; ++j) {                                      \
272*4e366538SXin Li         EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]);        \
273*4e366538SXin Li       }                                                                       \
274*4e366538SXin Li     }                                                                         \
275*4e366538SXin Li     for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                 \
276*4e366538SXin Li       for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                \
277*4e366538SXin Li         EXPECT_EQ(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j],              \
278*4e366538SXin Li                   dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]);           \
279*4e366538SXin Li       }                                                                       \
280*4e366538SXin Li     }                                                                         \
281*4e366538SXin Li     for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                 \
282*4e366538SXin Li       for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                \
283*4e366538SXin Li         EXPECT_EQ(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j],              \
284*4e366538SXin Li                   dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]);           \
285*4e366538SXin Li       }                                                                       \
286*4e366538SXin Li     }                                                                         \
287*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_c);                                    \
288*4e366538SXin Li     free_aligned_buffer_page_end(dst_u_c);                                    \
289*4e366538SXin Li     free_aligned_buffer_page_end(dst_v_c);                                    \
290*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_opt);                                  \
291*4e366538SXin Li     free_aligned_buffer_page_end(dst_u_opt);                                  \
292*4e366538SXin Li     free_aligned_buffer_page_end(dst_v_opt);                                  \
293*4e366538SXin Li     free_aligned_buffer_page_end(src_y);                                      \
294*4e366538SXin Li     free_aligned_buffer_page_end(src_uv);                                     \
295*4e366538SXin Li   }
296*4e366538SXin Li 
297*4e366538SXin Li #if defined(ENABLE_FULL_TESTS)
298*4e366538SXin Li #define TESTAPLANARTOP(SRC_FMT_PLANAR, PN, PIXEL_STRIDE, OFF_U, OFF_V,         \
299*4e366538SXin Li                        SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, SUBSAMP_X,    \
300*4e366538SXin Li                        SUBSAMP_Y)                                              \
301*4e366538SXin Li   TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
302*4e366538SXin Li                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_ + 1,      \
303*4e366538SXin Li                   _Any, +, 0, PN, OFF_U, OFF_V)                                \
304*4e366538SXin Li   TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
305*4e366538SXin Li                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_,          \
306*4e366538SXin Li                   _Unaligned, +, 2, PN, OFF_U, OFF_V)                          \
307*4e366538SXin Li   TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
308*4e366538SXin Li                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Invert, \
309*4e366538SXin Li                   -, 0, PN, OFF_U, OFF_V)                                      \
310*4e366538SXin Li   TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
311*4e366538SXin Li                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Opt, +, \
312*4e366538SXin Li                   0, PN, OFF_U, OFF_V)
313*4e366538SXin Li #else
314*4e366538SXin Li #define TESTAPLANARTOP(SRC_FMT_PLANAR, PN, PIXEL_STRIDE, OFF_U, OFF_V,         \
315*4e366538SXin Li                        SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, SUBSAMP_X,    \
316*4e366538SXin Li                        SUBSAMP_Y)                                              \
317*4e366538SXin Li   TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
318*4e366538SXin Li                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Opt, +, \
319*4e366538SXin Li                   0, PN, OFF_U, OFF_V)
320*4e366538SXin Li #endif
321*4e366538SXin Li 
322*4e366538SXin Li TESTAPLANARTOP(Android420, I420, 1, 0, 0, 2, 2, I420, 2, 2)
323*4e366538SXin Li TESTAPLANARTOP(Android420, NV12, 2, 0, 1, 2, 2, I420, 2, 2)
324*4e366538SXin Li TESTAPLANARTOP(Android420, NV21, 2, 1, 0, 2, 2, I420, 2, 2)
325*4e366538SXin Li #undef TESTAPLANARTOP
326*4e366538SXin Li #undef TESTAPLANARTOPI
327*4e366538SXin Li 
328*4e366538SXin Li // wrapper to keep API the same
I400ToNV21(const uint8_t * src_y,int src_stride_y,const uint8_t *,int,const uint8_t *,int,uint8_t * dst_y,int dst_stride_y,uint8_t * dst_vu,int dst_stride_vu,int width,int height)329*4e366538SXin Li int I400ToNV21(const uint8_t* src_y,
330*4e366538SXin Li                int src_stride_y,
331*4e366538SXin Li                const uint8_t* /* src_u */,
332*4e366538SXin Li                int /* src_stride_u */,
333*4e366538SXin Li                const uint8_t* /* src_v */,
334*4e366538SXin Li                int /* src_stride_v */,
335*4e366538SXin Li                uint8_t* dst_y,
336*4e366538SXin Li                int dst_stride_y,
337*4e366538SXin Li                uint8_t* dst_vu,
338*4e366538SXin Li                int dst_stride_vu,
339*4e366538SXin Li                int width,
340*4e366538SXin Li                int height) {
341*4e366538SXin Li   return I400ToNV21(src_y, src_stride_y, dst_y, dst_stride_y, dst_vu,
342*4e366538SXin Li                     dst_stride_vu, width, height);
343*4e366538SXin Li }
344*4e366538SXin Li 
345*4e366538SXin Li #define TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,        \
346*4e366538SXin Li                         SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC,            \
347*4e366538SXin Li                         DST_SUBSAMP_X, DST_SUBSAMP_Y, W1280, N, NEG, OFF,     \
348*4e366538SXin Li                         SRC_DEPTH)                                            \
349*4e366538SXin Li   TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {              \
350*4e366538SXin Li     static_assert(SRC_BPC == 1 || SRC_BPC == 2, "SRC BPC unsupported");       \
351*4e366538SXin Li     static_assert(DST_BPC == 1 || DST_BPC == 2, "DST BPC unsupported");       \
352*4e366538SXin Li     static_assert(SRC_SUBSAMP_X == 1 || SRC_SUBSAMP_X == 2,                   \
353*4e366538SXin Li                   "SRC_SUBSAMP_X unsupported");                               \
354*4e366538SXin Li     static_assert(SRC_SUBSAMP_Y == 1 || SRC_SUBSAMP_Y == 2,                   \
355*4e366538SXin Li                   "SRC_SUBSAMP_Y unsupported");                               \
356*4e366538SXin Li     static_assert(DST_SUBSAMP_X == 1 || DST_SUBSAMP_X == 2,                   \
357*4e366538SXin Li                   "DST_SUBSAMP_X unsupported");                               \
358*4e366538SXin Li     static_assert(DST_SUBSAMP_Y == 1 || DST_SUBSAMP_Y == 2,                   \
359*4e366538SXin Li                   "DST_SUBSAMP_Y unsupported");                               \
360*4e366538SXin Li     const int kWidth = W1280;                                                 \
361*4e366538SXin Li     const int kHeight = benchmark_height_;                                    \
362*4e366538SXin Li     const int kSrcHalfWidth = SUBSAMPLE(kWidth, SRC_SUBSAMP_X);               \
363*4e366538SXin Li     const int kSrcHalfHeight = SUBSAMPLE(kHeight, SRC_SUBSAMP_Y);             \
364*4e366538SXin Li     const int kDstHalfWidth = SUBSAMPLE(kWidth, DST_SUBSAMP_X);               \
365*4e366538SXin Li     const int kDstHalfHeight = SUBSAMPLE(kHeight, DST_SUBSAMP_Y);             \
366*4e366538SXin Li     align_buffer_page_end(src_y, kWidth* kHeight* SRC_BPC + OFF);             \
367*4e366538SXin Li     align_buffer_page_end(src_u,                                              \
368*4e366538SXin Li                           kSrcHalfWidth* kSrcHalfHeight* SRC_BPC + OFF);      \
369*4e366538SXin Li     align_buffer_page_end(src_v,                                              \
370*4e366538SXin Li                           kSrcHalfWidth* kSrcHalfHeight* SRC_BPC + OFF);      \
371*4e366538SXin Li     align_buffer_page_end(dst_y_c, kWidth* kHeight* DST_BPC);                 \
372*4e366538SXin Li     align_buffer_page_end(dst_uv_c,                                           \
373*4e366538SXin Li                           kDstHalfWidth* kDstHalfHeight* DST_BPC * 2);        \
374*4e366538SXin Li     align_buffer_page_end(dst_y_opt, kWidth* kHeight* DST_BPC);               \
375*4e366538SXin Li     align_buffer_page_end(dst_uv_opt,                                         \
376*4e366538SXin Li                           kDstHalfWidth* kDstHalfHeight* DST_BPC * 2);        \
377*4e366538SXin Li     MemRandomize(src_y + OFF, kWidth * kHeight * SRC_BPC);                    \
378*4e366538SXin Li     MemRandomize(src_u + OFF, kSrcHalfWidth * kSrcHalfHeight * SRC_BPC);      \
379*4e366538SXin Li     MemRandomize(src_v + OFF, kSrcHalfWidth * kSrcHalfHeight * SRC_BPC);      \
380*4e366538SXin Li     SRC_T* src_y_p = reinterpret_cast<SRC_T*>(src_y + OFF);                   \
381*4e366538SXin Li     SRC_T* src_u_p = reinterpret_cast<SRC_T*>(src_u + OFF);                   \
382*4e366538SXin Li     SRC_T* src_v_p = reinterpret_cast<SRC_T*>(src_v + OFF);                   \
383*4e366538SXin Li     for (int i = 0; i < kWidth * kHeight; ++i) {                              \
384*4e366538SXin Li       src_y_p[i] = src_y_p[i] & ((1 << SRC_DEPTH) - 1);                       \
385*4e366538SXin Li     }                                                                         \
386*4e366538SXin Li     for (int i = 0; i < kSrcHalfWidth * kSrcHalfHeight; ++i) {                \
387*4e366538SXin Li       src_u_p[i] = src_u_p[i] & ((1 << SRC_DEPTH) - 1);                       \
388*4e366538SXin Li       src_v_p[i] = src_v_p[i] & ((1 << SRC_DEPTH) - 1);                       \
389*4e366538SXin Li     }                                                                         \
390*4e366538SXin Li     memset(dst_y_c, 1, kWidth* kHeight* DST_BPC);                             \
391*4e366538SXin Li     memset(dst_uv_c, 2, kDstHalfWidth* kDstHalfHeight* DST_BPC * 2);          \
392*4e366538SXin Li     memset(dst_y_opt, 101, kWidth* kHeight* DST_BPC);                         \
393*4e366538SXin Li     memset(dst_uv_opt, 102, kDstHalfWidth* kDstHalfHeight* DST_BPC * 2);      \
394*4e366538SXin Li     MaskCpuFlags(disable_cpu_flags_);                                         \
395*4e366538SXin Li     SRC_FMT_PLANAR##To##FMT_PLANAR(src_y_p, kWidth, src_u_p, kSrcHalfWidth,   \
396*4e366538SXin Li                                    src_v_p, kSrcHalfWidth,                    \
397*4e366538SXin Li                                    reinterpret_cast<DST_T*>(dst_y_c), kWidth, \
398*4e366538SXin Li                                    reinterpret_cast<DST_T*>(dst_uv_c),        \
399*4e366538SXin Li                                    kDstHalfWidth * 2, kWidth, NEG kHeight);   \
400*4e366538SXin Li     MaskCpuFlags(benchmark_cpu_info_);                                        \
401*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                         \
402*4e366538SXin Li       SRC_FMT_PLANAR##To##FMT_PLANAR(                                         \
403*4e366538SXin Li           src_y_p, kWidth, src_u_p, kSrcHalfWidth, src_v_p, kSrcHalfWidth,    \
404*4e366538SXin Li           reinterpret_cast<DST_T*>(dst_y_opt), kWidth,                        \
405*4e366538SXin Li           reinterpret_cast<DST_T*>(dst_uv_opt), kDstHalfWidth * 2, kWidth,    \
406*4e366538SXin Li           NEG kHeight);                                                       \
407*4e366538SXin Li     }                                                                         \
408*4e366538SXin Li     for (int i = 0; i < kHeight * kWidth * DST_BPC; ++i) {                    \
409*4e366538SXin Li       EXPECT_EQ(dst_y_c[i], dst_y_opt[i]);                                    \
410*4e366538SXin Li     }                                                                         \
411*4e366538SXin Li     for (int i = 0; i < kDstHalfWidth * kDstHalfHeight * DST_BPC * 2; ++i) {  \
412*4e366538SXin Li       EXPECT_EQ(dst_uv_c[i], dst_uv_opt[i]);                                  \
413*4e366538SXin Li     }                                                                         \
414*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_c);                                    \
415*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_c);                                   \
416*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_opt);                                  \
417*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_opt);                                 \
418*4e366538SXin Li     free_aligned_buffer_page_end(src_y);                                      \
419*4e366538SXin Li     free_aligned_buffer_page_end(src_u);                                      \
420*4e366538SXin Li     free_aligned_buffer_page_end(src_v);                                      \
421*4e366538SXin Li   }
422*4e366538SXin Li 
423*4e366538SXin Li #if defined(ENABLE_FULL_TESTS)
424*4e366538SXin Li #define TESTPLANARTOBP(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,         \
425*4e366538SXin Li                        SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC,             \
426*4e366538SXin Li                        DST_SUBSAMP_X, DST_SUBSAMP_Y, SRC_DEPTH)               \
427*4e366538SXin Li   TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,              \
428*4e366538SXin Li                   SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X,   \
429*4e366538SXin Li                   DST_SUBSAMP_Y, benchmark_width_ + 1, _Any, +, 0, SRC_DEPTH) \
430*4e366538SXin Li   TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,              \
431*4e366538SXin Li                   SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X,   \
432*4e366538SXin Li                   DST_SUBSAMP_Y, benchmark_width_, _Unaligned, +, 2,          \
433*4e366538SXin Li                   SRC_DEPTH)                                                  \
434*4e366538SXin Li   TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,              \
435*4e366538SXin Li                   SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X,   \
436*4e366538SXin Li                   DST_SUBSAMP_Y, benchmark_width_, _Invert, -, 0, SRC_DEPTH)  \
437*4e366538SXin Li   TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,              \
438*4e366538SXin Li                   SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X,   \
439*4e366538SXin Li                   DST_SUBSAMP_Y, benchmark_width_, _Opt, +, 0, SRC_DEPTH)
440*4e366538SXin Li #else
441*4e366538SXin Li #define TESTPLANARTOBP(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,       \
442*4e366538SXin Li                        SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC,           \
443*4e366538SXin Li                        DST_SUBSAMP_X, DST_SUBSAMP_Y, SRC_DEPTH)             \
444*4e366538SXin Li   TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,            \
445*4e366538SXin Li                   SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, \
446*4e366538SXin Li                   DST_SUBSAMP_Y, benchmark_width_, _Opt, +, 0, SRC_DEPTH)
447*4e366538SXin Li #endif
448*4e366538SXin Li 
449*4e366538SXin Li TESTPLANARTOBP(I420, uint8_t, 1, 2, 2, NV12, uint8_t, 1, 2, 2, 8)
450*4e366538SXin Li TESTPLANARTOBP(I420, uint8_t, 1, 2, 2, NV21, uint8_t, 1, 2, 2, 8)
451*4e366538SXin Li TESTPLANARTOBP(I422, uint8_t, 1, 2, 1, NV21, uint8_t, 1, 2, 2, 8)
452*4e366538SXin Li TESTPLANARTOBP(I444, uint8_t, 1, 1, 1, NV12, uint8_t, 1, 2, 2, 8)
453*4e366538SXin Li TESTPLANARTOBP(I444, uint8_t, 1, 1, 1, NV21, uint8_t, 1, 2, 2, 8)
454*4e366538SXin Li TESTPLANARTOBP(I400, uint8_t, 1, 2, 2, NV21, uint8_t, 1, 2, 2, 8)
455*4e366538SXin Li TESTPLANARTOBP(I010, uint16_t, 2, 2, 2, P010, uint16_t, 2, 2, 2, 10)
456*4e366538SXin Li TESTPLANARTOBP(I210, uint16_t, 2, 2, 1, P210, uint16_t, 2, 2, 1, 10)
457*4e366538SXin Li TESTPLANARTOBP(I012, uint16_t, 2, 2, 2, P012, uint16_t, 2, 2, 2, 12)
458*4e366538SXin Li TESTPLANARTOBP(I212, uint16_t, 2, 2, 1, P212, uint16_t, 2, 2, 1, 12)
459*4e366538SXin Li 
460*4e366538SXin Li #define TESTBPTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,            \
461*4e366538SXin Li                     SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, \
462*4e366538SXin Li                     DST_SUBSAMP_Y, W1280, N, NEG, OFF, DOY, SRC_DEPTH,        \
463*4e366538SXin Li                     TILE_WIDTH, TILE_HEIGHT)                                  \
464*4e366538SXin Li   TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {              \
465*4e366538SXin Li     static_assert(DST_BPC == 1 || DST_BPC == 2, "DST BPC unsupported");       \
466*4e366538SXin Li     static_assert(SRC_SUBSAMP_X == 1 || SRC_SUBSAMP_X == 2,                   \
467*4e366538SXin Li                   "SRC_SUBSAMP_X unsupported");                               \
468*4e366538SXin Li     static_assert(SRC_SUBSAMP_Y == 1 || SRC_SUBSAMP_Y == 2,                   \
469*4e366538SXin Li                   "SRC_SUBSAMP_Y unsupported");                               \
470*4e366538SXin Li     static_assert(DST_SUBSAMP_X == 1 || DST_SUBSAMP_X == 2,                   \
471*4e366538SXin Li                   "DST_SUBSAMP_X unsupported");                               \
472*4e366538SXin Li     static_assert(DST_SUBSAMP_Y == 1 || DST_SUBSAMP_Y == 2,                   \
473*4e366538SXin Li                   "DST_SUBSAMP_Y unsupported");                               \
474*4e366538SXin Li     const int kWidth = W1280;                                                 \
475*4e366538SXin Li     const int kHeight = benchmark_height_;                                    \
476*4e366538SXin Li     const int kSrcHalfWidth = SUBSAMPLE(kWidth, SRC_SUBSAMP_X);               \
477*4e366538SXin Li     const int kDstHalfWidth = SUBSAMPLE(kWidth, DST_SUBSAMP_X);               \
478*4e366538SXin Li     const int kDstHalfHeight = SUBSAMPLE(kHeight, DST_SUBSAMP_Y);             \
479*4e366538SXin Li     const int kPaddedWidth = (kWidth + (TILE_WIDTH - 1)) & ~(TILE_WIDTH - 1); \
480*4e366538SXin Li     const int kPaddedHeight =                                                 \
481*4e366538SXin Li         (kHeight + (TILE_HEIGHT - 1)) & ~(TILE_HEIGHT - 1);                   \
482*4e366538SXin Li     const int kSrcHalfPaddedWidth = SUBSAMPLE(kPaddedWidth, SRC_SUBSAMP_X);   \
483*4e366538SXin Li     const int kSrcHalfPaddedHeight = SUBSAMPLE(kPaddedHeight, SRC_SUBSAMP_Y); \
484*4e366538SXin Li     align_buffer_page_end(src_y, kPaddedWidth* kPaddedHeight* SRC_BPC + OFF); \
485*4e366538SXin Li     align_buffer_page_end(                                                    \
486*4e366538SXin Li         src_uv,                                                               \
487*4e366538SXin Li         2 * kSrcHalfPaddedWidth * kSrcHalfPaddedHeight * SRC_BPC + OFF);      \
488*4e366538SXin Li     align_buffer_page_end(dst_y_c, kWidth* kHeight* DST_BPC);                 \
489*4e366538SXin Li     align_buffer_page_end(dst_uv_c,                                           \
490*4e366538SXin Li                           2 * kDstHalfWidth * kDstHalfHeight * DST_BPC);      \
491*4e366538SXin Li     align_buffer_page_end(dst_y_opt, kWidth* kHeight* DST_BPC);               \
492*4e366538SXin Li     align_buffer_page_end(dst_uv_opt,                                         \
493*4e366538SXin Li                           2 * kDstHalfWidth * kDstHalfHeight * DST_BPC);      \
494*4e366538SXin Li     SRC_T* src_y_p = reinterpret_cast<SRC_T*>(src_y + OFF);                   \
495*4e366538SXin Li     SRC_T* src_uv_p = reinterpret_cast<SRC_T*>(src_uv + OFF);                 \
496*4e366538SXin Li     for (int i = 0;                                                           \
497*4e366538SXin Li          i < kPaddedWidth * kPaddedHeight * SRC_BPC / (int)sizeof(SRC_T);     \
498*4e366538SXin Li          ++i) {                                                               \
499*4e366538SXin Li       src_y_p[i] =                                                            \
500*4e366538SXin Li           (fastrand() & (((SRC_T)(-1)) << ((8 * SRC_BPC) - SRC_DEPTH)));      \
501*4e366538SXin Li     }                                                                         \
502*4e366538SXin Li     for (int i = 0; i < kSrcHalfPaddedWidth * kSrcHalfPaddedHeight * 2 *      \
503*4e366538SXin Li                             SRC_BPC / (int)sizeof(SRC_T);                     \
504*4e366538SXin Li          ++i) {                                                               \
505*4e366538SXin Li       src_uv_p[i] =                                                           \
506*4e366538SXin Li           (fastrand() & (((SRC_T)(-1)) << ((8 * SRC_BPC) - SRC_DEPTH)));      \
507*4e366538SXin Li     }                                                                         \
508*4e366538SXin Li     memset(dst_y_c, 1, kWidth* kHeight* DST_BPC);                             \
509*4e366538SXin Li     memset(dst_uv_c, 2, 2 * kDstHalfWidth * kDstHalfHeight * DST_BPC);        \
510*4e366538SXin Li     memset(dst_y_opt, 101, kWidth* kHeight* DST_BPC);                         \
511*4e366538SXin Li     memset(dst_uv_opt, 102, 2 * kDstHalfWidth * kDstHalfHeight * DST_BPC);    \
512*4e366538SXin Li     MaskCpuFlags(disable_cpu_flags_);                                         \
513*4e366538SXin Li     SRC_FMT_PLANAR##To##FMT_PLANAR(                                           \
514*4e366538SXin Li         src_y_p, kWidth* SRC_BPC / (int)sizeof(SRC_T), src_uv_p,              \
515*4e366538SXin Li         2 * kSrcHalfWidth * SRC_BPC / (int)sizeof(SRC_T),                     \
516*4e366538SXin Li         DOY ? reinterpret_cast<DST_T*>(dst_y_c) : NULL, kWidth,               \
517*4e366538SXin Li         reinterpret_cast<DST_T*>(dst_uv_c), 2 * kDstHalfWidth, kWidth,        \
518*4e366538SXin Li         NEG kHeight);                                                         \
519*4e366538SXin Li     MaskCpuFlags(benchmark_cpu_info_);                                        \
520*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                         \
521*4e366538SXin Li       SRC_FMT_PLANAR##To##FMT_PLANAR(                                         \
522*4e366538SXin Li           src_y_p, kWidth* SRC_BPC / (int)sizeof(SRC_T), src_uv_p,            \
523*4e366538SXin Li           2 * kSrcHalfWidth * SRC_BPC / (int)sizeof(SRC_T),                   \
524*4e366538SXin Li           DOY ? reinterpret_cast<DST_T*>(dst_y_opt) : NULL, kWidth,           \
525*4e366538SXin Li           reinterpret_cast<DST_T*>(dst_uv_opt), 2 * kDstHalfWidth, kWidth,    \
526*4e366538SXin Li           NEG kHeight);                                                       \
527*4e366538SXin Li     }                                                                         \
528*4e366538SXin Li     if (DOY) {                                                                \
529*4e366538SXin Li       for (int i = 0; i < kHeight; ++i) {                                     \
530*4e366538SXin Li         for (int j = 0; j < kWidth; ++j) {                                    \
531*4e366538SXin Li           EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]);      \
532*4e366538SXin Li         }                                                                     \
533*4e366538SXin Li       }                                                                       \
534*4e366538SXin Li     }                                                                         \
535*4e366538SXin Li     for (int i = 0; i < kDstHalfHeight; ++i) {                                \
536*4e366538SXin Li       for (int j = 0; j < 2 * kDstHalfWidth; ++j) {                           \
537*4e366538SXin Li         EXPECT_EQ(dst_uv_c[i * 2 * kDstHalfWidth + j],                        \
538*4e366538SXin Li                   dst_uv_opt[i * 2 * kDstHalfWidth + j]);                     \
539*4e366538SXin Li       }                                                                       \
540*4e366538SXin Li     }                                                                         \
541*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_c);                                    \
542*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_c);                                   \
543*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_opt);                                  \
544*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_opt);                                 \
545*4e366538SXin Li     free_aligned_buffer_page_end(src_y);                                      \
546*4e366538SXin Li     free_aligned_buffer_page_end(src_uv);                                     \
547*4e366538SXin Li   }
548*4e366538SXin Li 
549*4e366538SXin Li #if defined(ENABLE_FULL_TESTS)
550*4e366538SXin Li #define TESTBPTOBP(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,            \
551*4e366538SXin Li                    SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, \
552*4e366538SXin Li                    DST_SUBSAMP_Y, SRC_DEPTH, TILE_WIDTH, TILE_HEIGHT)        \
553*4e366538SXin Li   TESTBPTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
554*4e366538SXin Li               FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,      \
555*4e366538SXin Li               benchmark_width_ + 1, _Any, +, 0, 1, SRC_DEPTH, TILE_WIDTH,    \
556*4e366538SXin Li               TILE_HEIGHT)                                                   \
557*4e366538SXin Li   TESTBPTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
558*4e366538SXin Li               FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,      \
559*4e366538SXin Li               benchmark_width_, _Unaligned, +, 2, 1, SRC_DEPTH, TILE_WIDTH,  \
560*4e366538SXin Li               TILE_HEIGHT)                                                   \
561*4e366538SXin Li   TESTBPTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
562*4e366538SXin Li               FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,      \
563*4e366538SXin Li               benchmark_width_, _Invert, -, 0, 1, SRC_DEPTH, TILE_WIDTH,     \
564*4e366538SXin Li               TILE_HEIGHT)                                                   \
565*4e366538SXin Li   TESTBPTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
566*4e366538SXin Li               FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,      \
567*4e366538SXin Li               benchmark_width_, _Opt, +, 0, 1, SRC_DEPTH, TILE_WIDTH,        \
568*4e366538SXin Li               TILE_HEIGHT)                                                   \
569*4e366538SXin Li   TESTBPTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
570*4e366538SXin Li               FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,      \
571*4e366538SXin Li               benchmark_width_, _NullY, +, 0, 0, SRC_DEPTH, TILE_WIDTH,      \
572*4e366538SXin Li               TILE_HEIGHT)
573*4e366538SXin Li #else
574*4e366538SXin Li #define TESTBPTOBP(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X,            \
575*4e366538SXin Li                    SRC_SUBSAMP_Y, FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, \
576*4e366538SXin Li                    DST_SUBSAMP_Y, SRC_DEPTH, TILE_WIDTH, TILE_HEIGHT)        \
577*4e366538SXin Li   TESTBPTOBPI(SRC_FMT_PLANAR, SRC_T, SRC_BPC, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,  \
578*4e366538SXin Li               FMT_PLANAR, DST_T, DST_BPC, DST_SUBSAMP_X, DST_SUBSAMP_Y,      \
579*4e366538SXin Li               benchmark_width_, _NullY, +, 0, 0, SRC_DEPTH, TILE_WIDTH,      \
580*4e366538SXin Li               TILE_HEIGHT)
581*4e366538SXin Li #endif
582*4e366538SXin Li 
583*4e366538SXin Li TESTBPTOBP(NV21, uint8_t, 1, 2, 2, NV12, uint8_t, 1, 2, 2, 8, 1, 1)
584*4e366538SXin Li TESTBPTOBP(NV12, uint8_t, 1, 2, 2, NV12Mirror, uint8_t, 1, 2, 2, 8, 1, 1)
585*4e366538SXin Li TESTBPTOBP(NV12, uint8_t, 1, 2, 2, NV24, uint8_t, 1, 1, 1, 8, 1, 1)
586*4e366538SXin Li TESTBPTOBP(NV16, uint8_t, 1, 2, 1, NV24, uint8_t, 1, 1, 1, 8, 1, 1)
587*4e366538SXin Li TESTBPTOBP(P010, uint16_t, 2, 2, 2, P410, uint16_t, 2, 1, 1, 10, 1, 1)
588*4e366538SXin Li TESTBPTOBP(P210, uint16_t, 2, 2, 1, P410, uint16_t, 2, 1, 1, 10, 1, 1)
589*4e366538SXin Li TESTBPTOBP(P012, uint16_t, 2, 2, 2, P412, uint16_t, 2, 1, 1, 10, 1, 1)
590*4e366538SXin Li TESTBPTOBP(P212, uint16_t, 2, 2, 1, P412, uint16_t, 2, 1, 1, 12, 1, 1)
591*4e366538SXin Li TESTBPTOBP(P016, uint16_t, 2, 2, 2, P416, uint16_t, 2, 1, 1, 12, 1, 1)
592*4e366538SXin Li TESTBPTOBP(P216, uint16_t, 2, 2, 1, P416, uint16_t, 2, 1, 1, 12, 1, 1)
593*4e366538SXin Li TESTBPTOBP(MM21, uint8_t, 1, 2, 2, NV12, uint8_t, 1, 2, 2, 8, 16, 32)
594*4e366538SXin Li TESTBPTOBP(MT2T, uint8_t, 10 / 8, 2, 2, P010, uint16_t, 2, 2, 2, 10, 16, 32)
595*4e366538SXin Li 
596*4e366538SXin Li #define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
597*4e366538SXin Li                        W1280, N, NEG, OFF)                                     \
598*4e366538SXin Li   TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) {                        \
599*4e366538SXin Li     const int kWidth = W1280;                                                  \
600*4e366538SXin Li     const int kHeight = ALIGNINT(benchmark_height_, YALIGN);                   \
601*4e366538SXin Li     const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X);                        \
602*4e366538SXin Li     const int kStride = (kStrideUV * SUBSAMP_X * 8 * BPP_A + 7) / 8;           \
603*4e366538SXin Li     align_buffer_page_end(src_argb, kStride* kHeight + OFF);                   \
604*4e366538SXin Li     align_buffer_page_end(dst_y_c, kWidth* kHeight);                           \
605*4e366538SXin Li     align_buffer_page_end(dst_uv_c,                                            \
606*4e366538SXin Li                           kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));      \
607*4e366538SXin Li     align_buffer_page_end(dst_y_opt, kWidth* kHeight);                         \
608*4e366538SXin Li     align_buffer_page_end(dst_uv_opt,                                          \
609*4e366538SXin Li                           kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));      \
610*4e366538SXin Li     memset(dst_y_c, 1, kWidth* kHeight);                                       \
611*4e366538SXin Li     memset(dst_uv_c, 2, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
612*4e366538SXin Li     memset(dst_y_opt, 101, kWidth* kHeight);                                   \
613*4e366538SXin Li     memset(dst_uv_opt, 102, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));    \
614*4e366538SXin Li     for (int i = 0; i < kHeight; ++i)                                          \
615*4e366538SXin Li       for (int j = 0; j < kStride; ++j)                                        \
616*4e366538SXin Li         src_argb[(i * kStride) + j + OFF] = (fastrand() & 0xff);               \
617*4e366538SXin Li     MaskCpuFlags(disable_cpu_flags_);                                          \
618*4e366538SXin Li     FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_c, kWidth, dst_uv_c,  \
619*4e366538SXin Li                           kStrideUV * 2, dst_uv_c + kStrideUV, kStrideUV * 2,  \
620*4e366538SXin Li                           kWidth, NEG kHeight);                                \
621*4e366538SXin Li     MaskCpuFlags(benchmark_cpu_info_);                                         \
622*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                          \
623*4e366538SXin Li       FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_opt, kWidth,        \
624*4e366538SXin Li                             dst_uv_opt, kStrideUV * 2, dst_uv_opt + kStrideUV, \
625*4e366538SXin Li                             kStrideUV * 2, kWidth, NEG kHeight);               \
626*4e366538SXin Li     }                                                                          \
627*4e366538SXin Li     for (int i = 0; i < kHeight; ++i) {                                        \
628*4e366538SXin Li       for (int j = 0; j < kWidth; ++j) {                                       \
629*4e366538SXin Li         EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]);         \
630*4e366538SXin Li       }                                                                        \
631*4e366538SXin Li     }                                                                          \
632*4e366538SXin Li     for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * 2; ++i) {              \
633*4e366538SXin Li       for (int j = 0; j < kStrideUV; ++j) {                                    \
634*4e366538SXin Li         EXPECT_EQ(dst_uv_c[i * kStrideUV + j], dst_uv_opt[i * kStrideUV + j]); \
635*4e366538SXin Li       }                                                                        \
636*4e366538SXin Li     }                                                                          \
637*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_c);                                     \
638*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_c);                                    \
639*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_opt);                                   \
640*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_opt);                                  \
641*4e366538SXin Li     free_aligned_buffer_page_end(src_argb);                                    \
642*4e366538SXin Li   }
643*4e366538SXin Li 
644*4e366538SXin Li #if defined(ENABLE_FULL_TESTS)
645*4e366538SXin Li #define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
646*4e366538SXin Li   TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
647*4e366538SXin Li                  benchmark_width_ + 1, _Any, +, 0)                            \
648*4e366538SXin Li   TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
649*4e366538SXin Li                  benchmark_width_, _Unaligned, +, 2)                          \
650*4e366538SXin Li   TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
651*4e366538SXin Li                  benchmark_width_, _Invert, -, 0)                             \
652*4e366538SXin Li   TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
653*4e366538SXin Li                  benchmark_width_, _Opt, +, 0)
654*4e366538SXin Li #else
655*4e366538SXin Li #define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
656*4e366538SXin Li   TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
657*4e366538SXin Li                  benchmark_width_, _Opt, +, 0)
658*4e366538SXin Li #endif
659*4e366538SXin Li 
660*4e366538SXin Li TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2)
661*4e366538SXin Li TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2)
662*4e366538SXin Li TESTATOPLANAR(ARGB, 4, 1, I422, 2, 1)
663*4e366538SXin Li TESTATOPLANAR(ARGB, 4, 1, I444, 1, 1)
664*4e366538SXin Li TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2)
665*4e366538SXin Li TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1)
666*4e366538SXin Li TESTATOPLANAR(ABGR, 4, 1, J420, 2, 2)
667*4e366538SXin Li TESTATOPLANAR(ABGR, 4, 1, J422, 2, 1)
668*4e366538SXin Li #ifdef LITTLE_ENDIAN_ONLY_TEST
669*4e366538SXin Li TESTATOPLANAR(ARGB4444, 2, 1, I420, 2, 2)
670*4e366538SXin Li TESTATOPLANAR(RGB565, 2, 1, I420, 2, 2)
671*4e366538SXin Li TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2)
672*4e366538SXin Li #endif
673*4e366538SXin Li TESTATOPLANAR(BGRA, 4, 1, I420, 2, 2)
674*4e366538SXin Li TESTATOPLANAR(I400, 1, 1, I420, 2, 2)
675*4e366538SXin Li TESTATOPLANAR(J400, 1, 1, J420, 2, 2)
676*4e366538SXin Li TESTATOPLANAR(RAW, 3, 1, I420, 2, 2)
677*4e366538SXin Li TESTATOPLANAR(RAW, 3, 1, J420, 2, 2)
678*4e366538SXin Li TESTATOPLANAR(RGB24, 3, 1, I420, 2, 2)
679*4e366538SXin Li TESTATOPLANAR(RGB24, 3, 1, J420, 2, 2)
680*4e366538SXin Li TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2)
681*4e366538SXin Li TESTATOPLANAR(UYVY, 2, 1, I420, 2, 2)
682*4e366538SXin Li TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1)
683*4e366538SXin Li TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2)
684*4e366538SXin Li TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1)
685*4e366538SXin Li 
686*4e366538SXin Li #define TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X,           \
687*4e366538SXin Li                         SUBSAMP_Y, W1280, N, NEG, OFF)                         \
688*4e366538SXin Li   TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) {                        \
689*4e366538SXin Li     const int kWidth = W1280;                                                  \
690*4e366538SXin Li     const int kHeight = ALIGNINT(benchmark_height_, YALIGN);                   \
691*4e366538SXin Li     const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X);                        \
692*4e366538SXin Li     const int kStride = (kStrideUV * SUBSAMP_X * 8 * BPP_A + 7) / 8;           \
693*4e366538SXin Li     align_buffer_page_end(src_argb, kStride* kHeight + OFF);                   \
694*4e366538SXin Li     align_buffer_page_end(dst_a_c, kWidth* kHeight);                           \
695*4e366538SXin Li     align_buffer_page_end(dst_y_c, kWidth* kHeight);                           \
696*4e366538SXin Li     align_buffer_page_end(dst_uv_c,                                            \
697*4e366538SXin Li                           kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));      \
698*4e366538SXin Li     align_buffer_page_end(dst_a_opt, kWidth* kHeight);                         \
699*4e366538SXin Li     align_buffer_page_end(dst_y_opt, kWidth* kHeight);                         \
700*4e366538SXin Li     align_buffer_page_end(dst_uv_opt,                                          \
701*4e366538SXin Li                           kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));      \
702*4e366538SXin Li     memset(dst_a_c, 1, kWidth* kHeight);                                       \
703*4e366538SXin Li     memset(dst_y_c, 2, kWidth* kHeight);                                       \
704*4e366538SXin Li     memset(dst_uv_c, 3, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
705*4e366538SXin Li     memset(dst_a_opt, 101, kWidth* kHeight);                                   \
706*4e366538SXin Li     memset(dst_y_opt, 102, kWidth* kHeight);                                   \
707*4e366538SXin Li     memset(dst_uv_opt, 103, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));    \
708*4e366538SXin Li     for (int i = 0; i < kHeight; ++i)                                          \
709*4e366538SXin Li       for (int j = 0; j < kStride; ++j)                                        \
710*4e366538SXin Li         src_argb[(i * kStride) + j + OFF] = (fastrand() & 0xff);               \
711*4e366538SXin Li     MaskCpuFlags(disable_cpu_flags_);                                          \
712*4e366538SXin Li     FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_c, kWidth, dst_uv_c,  \
713*4e366538SXin Li                           kStrideUV * 2, dst_uv_c + kStrideUV, kStrideUV * 2,  \
714*4e366538SXin Li                           dst_a_c, kWidth, kWidth, NEG kHeight);               \
715*4e366538SXin Li     MaskCpuFlags(benchmark_cpu_info_);                                         \
716*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                          \
717*4e366538SXin Li       FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_opt, kWidth,        \
718*4e366538SXin Li                             dst_uv_opt, kStrideUV * 2, dst_uv_opt + kStrideUV, \
719*4e366538SXin Li                             kStrideUV * 2, dst_a_opt, kWidth, kWidth,          \
720*4e366538SXin Li                             NEG kHeight);                                      \
721*4e366538SXin Li     }                                                                          \
722*4e366538SXin Li     for (int i = 0; i < kHeight; ++i) {                                        \
723*4e366538SXin Li       for (int j = 0; j < kWidth; ++j) {                                       \
724*4e366538SXin Li         EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]);         \
725*4e366538SXin Li         EXPECT_EQ(dst_a_c[i * kWidth + j], dst_a_opt[i * kWidth + j]);         \
726*4e366538SXin Li       }                                                                        \
727*4e366538SXin Li     }                                                                          \
728*4e366538SXin Li     for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * 2; ++i) {              \
729*4e366538SXin Li       for (int j = 0; j < kStrideUV; ++j) {                                    \
730*4e366538SXin Li         EXPECT_EQ(dst_uv_c[i * kStrideUV + j], dst_uv_opt[i * kStrideUV + j]); \
731*4e366538SXin Li       }                                                                        \
732*4e366538SXin Li     }                                                                          \
733*4e366538SXin Li     free_aligned_buffer_page_end(dst_a_c);                                     \
734*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_c);                                     \
735*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_c);                                    \
736*4e366538SXin Li     free_aligned_buffer_page_end(dst_a_opt);                                   \
737*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_opt);                                   \
738*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_opt);                                  \
739*4e366538SXin Li     free_aligned_buffer_page_end(src_argb);                                    \
740*4e366538SXin Li   }
741*4e366538SXin Li 
742*4e366538SXin Li #if defined(ENABLE_FULL_TESTS)
743*4e366538SXin Li #define TESTATOPLANARA(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
744*4e366538SXin Li   TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
745*4e366538SXin Li                   benchmark_width_ + 1, _Any, +, 0)                            \
746*4e366538SXin Li   TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
747*4e366538SXin Li                   benchmark_width_, _Unaligned, +, 2)                          \
748*4e366538SXin Li   TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
749*4e366538SXin Li                   benchmark_width_, _Invert, -, 0)                             \
750*4e366538SXin Li   TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
751*4e366538SXin Li                   benchmark_width_, _Opt, +, 0)
752*4e366538SXin Li #else
753*4e366538SXin Li #define TESTATOPLANARA(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
754*4e366538SXin Li   TESTATOPLANARAI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
755*4e366538SXin Li                   benchmark_width_, _Opt, +, 0)
756*4e366538SXin Li #endif
757*4e366538SXin Li 
758*4e366538SXin Li TESTATOPLANARA(ARGB, 4, 1, I420Alpha, 2, 2)
759*4e366538SXin Li 
760*4e366538SXin Li #define TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
761*4e366538SXin Li                    W1280, N, NEG, OFF)                                        \
762*4e366538SXin Li   TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) {                       \
763*4e366538SXin Li     const int kWidth = W1280;                                                 \
764*4e366538SXin Li     const int kHeight = benchmark_height_;                                    \
765*4e366538SXin Li     const int kStride = SUBSAMPLE(kWidth, SUB_A) * BPP_A;                     \
766*4e366538SXin Li     const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X);                       \
767*4e366538SXin Li     align_buffer_page_end(src_argb, kStride* kHeight + OFF);                  \
768*4e366538SXin Li     align_buffer_page_end(dst_y_c, kWidth* kHeight);                          \
769*4e366538SXin Li     align_buffer_page_end(dst_uv_c,                                           \
770*4e366538SXin Li                           kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));     \
771*4e366538SXin Li     align_buffer_page_end(dst_y_opt, kWidth* kHeight);                        \
772*4e366538SXin Li     align_buffer_page_end(dst_uv_opt,                                         \
773*4e366538SXin Li                           kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));     \
774*4e366538SXin Li     for (int i = 0; i < kHeight; ++i)                                         \
775*4e366538SXin Li       for (int j = 0; j < kStride; ++j)                                       \
776*4e366538SXin Li         src_argb[(i * kStride) + j + OFF] = (fastrand() & 0xff);              \
777*4e366538SXin Li     memset(dst_y_c, 1, kWidth* kHeight);                                      \
778*4e366538SXin Li     memset(dst_uv_c, 2, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));       \
779*4e366538SXin Li     memset(dst_y_opt, 101, kWidth* kHeight);                                  \
780*4e366538SXin Li     memset(dst_uv_opt, 102, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y));   \
781*4e366538SXin Li     MaskCpuFlags(disable_cpu_flags_);                                         \
782*4e366538SXin Li     FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_c, kWidth, dst_uv_c, \
783*4e366538SXin Li                           kStrideUV * 2, kWidth, NEG kHeight);                \
784*4e366538SXin Li     MaskCpuFlags(benchmark_cpu_info_);                                        \
785*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                         \
786*4e366538SXin Li       FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, dst_y_opt, kWidth,       \
787*4e366538SXin Li                             dst_uv_opt, kStrideUV * 2, kWidth, NEG kHeight);  \
788*4e366538SXin Li     }                                                                         \
789*4e366538SXin Li     for (int i = 0; i < kHeight; ++i) {                                       \
790*4e366538SXin Li       for (int j = 0; j < kWidth; ++j) {                                      \
791*4e366538SXin Li         EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]);        \
792*4e366538SXin Li       }                                                                       \
793*4e366538SXin Li     }                                                                         \
794*4e366538SXin Li     for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                 \
795*4e366538SXin Li       for (int j = 0; j < kStrideUV * 2; ++j) {                               \
796*4e366538SXin Li         EXPECT_EQ(dst_uv_c[i * kStrideUV * 2 + j],                            \
797*4e366538SXin Li                   dst_uv_opt[i * kStrideUV * 2 + j]);                         \
798*4e366538SXin Li       }                                                                       \
799*4e366538SXin Li     }                                                                         \
800*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_c);                                    \
801*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_c);                                   \
802*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_opt);                                  \
803*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_opt);                                 \
804*4e366538SXin Li     free_aligned_buffer_page_end(src_argb);                                   \
805*4e366538SXin Li   }
806*4e366538SXin Li 
807*4e366538SXin Li #if defined(ENABLE_FULL_TESTS)
808*4e366538SXin Li #define TESTATOBP(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
809*4e366538SXin Li   TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
810*4e366538SXin Li              benchmark_width_ + 1, _Any, +, 0)                           \
811*4e366538SXin Li   TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
812*4e366538SXin Li              benchmark_width_, _Unaligned, +, 2)                         \
813*4e366538SXin Li   TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
814*4e366538SXin Li              benchmark_width_, _Invert, -, 0)                            \
815*4e366538SXin Li   TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
816*4e366538SXin Li              benchmark_width_, _Opt, +, 0)
817*4e366538SXin Li #else
818*4e366538SXin Li #define TESTATOBP(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
819*4e366538SXin Li   TESTATOBPI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,      \
820*4e366538SXin Li              benchmark_width_, _Opt, +, 0)
821*4e366538SXin Li #endif
822*4e366538SXin Li 
823*4e366538SXin Li TESTATOBP(ARGB, 1, 4, NV12, 2, 2)
824*4e366538SXin Li TESTATOBP(ARGB, 1, 4, NV21, 2, 2)
825*4e366538SXin Li TESTATOBP(ABGR, 1, 4, NV12, 2, 2)
826*4e366538SXin Li TESTATOBP(ABGR, 1, 4, NV21, 2, 2)
827*4e366538SXin Li TESTATOBP(RAW, 1, 3, JNV21, 2, 2)
828*4e366538SXin Li TESTATOBP(YUY2, 2, 4, NV12, 2, 2)
829*4e366538SXin Li TESTATOBP(UYVY, 2, 4, NV12, 2, 2)
830*4e366538SXin Li TESTATOBP(AYUV, 1, 4, NV12, 2, 2)
831*4e366538SXin Li TESTATOBP(AYUV, 1, 4, NV21, 2, 2)
832*4e366538SXin Li 
833*4e366538SXin Li #if !defined(LEAN_TESTS)
834*4e366538SXin Li 
835*4e366538SXin Li #ifdef HAVE_JPEG
TEST_F(LibYUVConvertTest,ValidateJpeg)836*4e366538SXin Li TEST_F(LibYUVConvertTest, ValidateJpeg) {
837*4e366538SXin Li   const int kOff = 10;
838*4e366538SXin Li   const int kMinJpeg = 64;
839*4e366538SXin Li   const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg
840*4e366538SXin Li                              ? benchmark_width_ * benchmark_height_
841*4e366538SXin Li                              : kMinJpeg;
842*4e366538SXin Li   const int kSize = kImageSize + kOff;
843*4e366538SXin Li   align_buffer_page_end(orig_pixels, kSize);
844*4e366538SXin Li 
845*4e366538SXin Li   // No SOI or EOI. Expect fail.
846*4e366538SXin Li   memset(orig_pixels, 0, kSize);
847*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
848*4e366538SXin Li 
849*4e366538SXin Li   // Test special value that matches marker start.
850*4e366538SXin Li   memset(orig_pixels, 0xff, kSize);
851*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
852*4e366538SXin Li 
853*4e366538SXin Li   // EOI, SOI. Expect pass.
854*4e366538SXin Li   orig_pixels[0] = 0xff;
855*4e366538SXin Li   orig_pixels[1] = 0xd8;  // SOI.
856*4e366538SXin Li   orig_pixels[2] = 0xff;
857*4e366538SXin Li   orig_pixels[kSize - kOff + 0] = 0xff;
858*4e366538SXin Li   orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
859*4e366538SXin Li   for (int times = 0; times < benchmark_iterations_; ++times) {
860*4e366538SXin Li     EXPECT_TRUE(ValidateJpeg(orig_pixels, kSize));
861*4e366538SXin Li   }
862*4e366538SXin Li   free_aligned_buffer_page_end(orig_pixels);
863*4e366538SXin Li }
864*4e366538SXin Li 
TEST_F(LibYUVConvertTest,ValidateJpegLarge)865*4e366538SXin Li TEST_F(LibYUVConvertTest, ValidateJpegLarge) {
866*4e366538SXin Li   const int kOff = 10;
867*4e366538SXin Li   const int kMinJpeg = 64;
868*4e366538SXin Li   const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg
869*4e366538SXin Li                              ? benchmark_width_ * benchmark_height_
870*4e366538SXin Li                              : kMinJpeg;
871*4e366538SXin Li   const int kSize = kImageSize + kOff;
872*4e366538SXin Li   const int kMultiple = 10;
873*4e366538SXin Li   const int kBufSize = kImageSize * kMultiple + kOff;
874*4e366538SXin Li   align_buffer_page_end(orig_pixels, kBufSize);
875*4e366538SXin Li 
876*4e366538SXin Li   // No SOI or EOI. Expect fail.
877*4e366538SXin Li   memset(orig_pixels, 0, kBufSize);
878*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(orig_pixels, kBufSize));
879*4e366538SXin Li 
880*4e366538SXin Li   // EOI, SOI. Expect pass.
881*4e366538SXin Li   orig_pixels[0] = 0xff;
882*4e366538SXin Li   orig_pixels[1] = 0xd8;  // SOI.
883*4e366538SXin Li   orig_pixels[2] = 0xff;
884*4e366538SXin Li   orig_pixels[kSize - kOff + 0] = 0xff;
885*4e366538SXin Li   orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
886*4e366538SXin Li   for (int times = 0; times < benchmark_iterations_; ++times) {
887*4e366538SXin Li     EXPECT_TRUE(ValidateJpeg(orig_pixels, kBufSize));
888*4e366538SXin Li   }
889*4e366538SXin Li   free_aligned_buffer_page_end(orig_pixels);
890*4e366538SXin Li }
891*4e366538SXin Li 
TEST_F(LibYUVConvertTest,InvalidateJpeg)892*4e366538SXin Li TEST_F(LibYUVConvertTest, InvalidateJpeg) {
893*4e366538SXin Li   const int kOff = 10;
894*4e366538SXin Li   const int kMinJpeg = 64;
895*4e366538SXin Li   const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg
896*4e366538SXin Li                              ? benchmark_width_ * benchmark_height_
897*4e366538SXin Li                              : kMinJpeg;
898*4e366538SXin Li   const int kSize = kImageSize + kOff;
899*4e366538SXin Li   align_buffer_page_end(orig_pixels, kSize);
900*4e366538SXin Li 
901*4e366538SXin Li   // NULL pointer. Expect fail.
902*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(NULL, kSize));
903*4e366538SXin Li 
904*4e366538SXin Li   // Negative size. Expect fail.
905*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(orig_pixels, -1));
906*4e366538SXin Li 
907*4e366538SXin Li   // Too large size. Expect fail.
908*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(orig_pixels, 0xfb000000ull));
909*4e366538SXin Li 
910*4e366538SXin Li   // No SOI or EOI. Expect fail.
911*4e366538SXin Li   memset(orig_pixels, 0, kSize);
912*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
913*4e366538SXin Li 
914*4e366538SXin Li   // SOI but no EOI. Expect fail.
915*4e366538SXin Li   orig_pixels[0] = 0xff;
916*4e366538SXin Li   orig_pixels[1] = 0xd8;  // SOI.
917*4e366538SXin Li   orig_pixels[2] = 0xff;
918*4e366538SXin Li   for (int times = 0; times < benchmark_iterations_; ++times) {
919*4e366538SXin Li     EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
920*4e366538SXin Li   }
921*4e366538SXin Li 
922*4e366538SXin Li   // EOI but no SOI. Expect fail.
923*4e366538SXin Li   orig_pixels[0] = 0;
924*4e366538SXin Li   orig_pixels[1] = 0;
925*4e366538SXin Li   orig_pixels[kSize - kOff + 0] = 0xff;
926*4e366538SXin Li   orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
927*4e366538SXin Li   EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
928*4e366538SXin Li 
929*4e366538SXin Li   free_aligned_buffer_page_end(orig_pixels);
930*4e366538SXin Li }
931*4e366538SXin Li 
TEST_F(LibYUVConvertTest,FuzzJpeg)932*4e366538SXin Li TEST_F(LibYUVConvertTest, FuzzJpeg) {
933*4e366538SXin Li   // SOI but no EOI. Expect fail.
934*4e366538SXin Li   for (int times = 0; times < benchmark_iterations_; ++times) {
935*4e366538SXin Li     const int kSize = fastrand() % 5000 + 3;
936*4e366538SXin Li     align_buffer_page_end(orig_pixels, kSize);
937*4e366538SXin Li     MemRandomize(orig_pixels, kSize);
938*4e366538SXin Li 
939*4e366538SXin Li     // Add SOI so frame will be scanned.
940*4e366538SXin Li     orig_pixels[0] = 0xff;
941*4e366538SXin Li     orig_pixels[1] = 0xd8;  // SOI.
942*4e366538SXin Li     orig_pixels[2] = 0xff;
943*4e366538SXin Li     orig_pixels[kSize - 1] = 0xff;
944*4e366538SXin Li     ValidateJpeg(orig_pixels,
945*4e366538SXin Li                  kSize);  // Failure normally expected.
946*4e366538SXin Li     free_aligned_buffer_page_end(orig_pixels);
947*4e366538SXin Li   }
948*4e366538SXin Li }
949*4e366538SXin Li 
950*4e366538SXin Li // Test data created in GIMP.  In export jpeg, disable
951*4e366538SXin Li // thumbnails etc, choose a subsampling, and use low quality
952*4e366538SXin Li // (50) to keep size small. Generated with xxd -i test.jpg
953*4e366538SXin Li // test 0 is J400
954*4e366538SXin Li static const uint8_t kTest0Jpg[] = {
955*4e366538SXin Li     0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
956*4e366538SXin Li     0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
957*4e366538SXin Li     0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, 0x0e, 0x12,
958*4e366538SXin Li     0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23,
959*4e366538SXin Li     0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40,
960*4e366538SXin Li     0x48, 0x5c, 0x4e, 0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51,
961*4e366538SXin Li     0x57, 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64,
962*4e366538SXin Li     0x78, 0x5c, 0x65, 0x67, 0x63, 0xff, 0xc2, 0x00, 0x0b, 0x08, 0x00, 0x10,
963*4e366538SXin Li     0x00, 0x20, 0x01, 0x01, 0x11, 0x00, 0xff, 0xc4, 0x00, 0x17, 0x00, 0x01,
964*4e366538SXin Li     0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
965*4e366538SXin Li     0x00, 0x00, 0x00, 0x03, 0x04, 0x01, 0x02, 0xff, 0xda, 0x00, 0x08, 0x01,
966*4e366538SXin Li     0x01, 0x00, 0x00, 0x00, 0x01, 0x43, 0x7e, 0xa7, 0x97, 0x57, 0xff, 0xc4,
967*4e366538SXin Li     0x00, 0x1b, 0x10, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00,
968*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x11, 0x00, 0x03,
969*4e366538SXin Li     0x10, 0x12, 0x13, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x05,
970*4e366538SXin Li     0x02, 0x3b, 0xc0, 0x6f, 0x66, 0x76, 0x56, 0x23, 0x87, 0x99, 0x0d, 0x26,
971*4e366538SXin Li     0x62, 0xf6, 0xbf, 0xff, 0xc4, 0x00, 0x1e, 0x10, 0x00, 0x02, 0x01, 0x03,
972*4e366538SXin Li     0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
973*4e366538SXin Li     0x00, 0x11, 0x21, 0x02, 0x12, 0x32, 0x10, 0x31, 0x71, 0x81, 0xa1, 0xff,
974*4e366538SXin Li     0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x06, 0x3f, 0x02, 0x4b, 0xb3, 0x28,
975*4e366538SXin Li     0x32, 0xd2, 0xed, 0xf9, 0x1d, 0x3e, 0x13, 0x51, 0x73, 0x83, 0xff, 0xc4,
976*4e366538SXin Li     0x00, 0x1c, 0x10, 0x01, 0x01, 0x01, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00,
977*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x21, 0x51,
978*4e366538SXin Li     0x31, 0x61, 0x81, 0xf0, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01,
979*4e366538SXin Li     0x3f, 0x21, 0x65, 0x6e, 0x31, 0x86, 0x28, 0xf9, 0x30, 0xdc, 0x27, 0xdb,
980*4e366538SXin Li     0xa9, 0x01, 0xf3, 0xde, 0x02, 0xa0, 0xed, 0x1e, 0x34, 0x68, 0x23, 0xf9,
981*4e366538SXin Li     0xc6, 0x48, 0x5d, 0x7a, 0x35, 0x02, 0xf5, 0x6f, 0xff, 0xda, 0x00, 0x08,
982*4e366538SXin Li     0x01, 0x01, 0x00, 0x00, 0x00, 0x10, 0x35, 0xff, 0xc4, 0x00, 0x1f, 0x10,
983*4e366538SXin Li     0x01, 0x00, 0x02, 0x01, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
984*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x31, 0x41, 0x61, 0x71, 0x91,
985*4e366538SXin Li     0x21, 0x81, 0xd1, 0xb1, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01,
986*4e366538SXin Li     0x3f, 0x10, 0x0b, 0x30, 0xe9, 0x58, 0xbe, 0x1a, 0xfd, 0x88, 0xab, 0x8b,
987*4e366538SXin Li     0x34, 0x74, 0x80, 0x4b, 0xb5, 0xd5, 0xab, 0xcd, 0x46, 0x96, 0x2e, 0xec,
988*4e366538SXin Li     0xbd, 0xaa, 0x78, 0x47, 0x5c, 0x47, 0xa7, 0x30, 0x49, 0xad, 0x88, 0x7c,
989*4e366538SXin Li     0x40, 0x74, 0x30, 0xff, 0x00, 0x23, 0x1d, 0x03, 0x0b, 0xb7, 0xd4, 0xff,
990*4e366538SXin Li     0xd9};
991*4e366538SXin Li static const size_t kTest0JpgLen = 421;
992*4e366538SXin Li 
993*4e366538SXin Li // test 1 is J444
994*4e366538SXin Li static const uint8_t kTest1Jpg[] = {
995*4e366538SXin Li     0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
996*4e366538SXin Li     0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
997*4e366538SXin Li     0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, 0x0e, 0x12,
998*4e366538SXin Li     0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23,
999*4e366538SXin Li     0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40,
1000*4e366538SXin Li     0x48, 0x5c, 0x4e, 0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51,
1001*4e366538SXin Li     0x57, 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64,
1002*4e366538SXin Li     0x78, 0x5c, 0x65, 0x67, 0x63, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x11, 0x12,
1003*4e366538SXin Li     0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42,
1004*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1005*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1006*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1007*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1008*4e366538SXin Li     0x63, 0x63, 0xff, 0xc2, 0x00, 0x11, 0x08, 0x00, 0x10, 0x00, 0x20, 0x03,
1009*4e366538SXin Li     0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
1010*4e366538SXin Li     0x17, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1011*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x01, 0x02, 0xff, 0xc4,
1012*4e366538SXin Li     0x00, 0x16, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1013*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0xff, 0xda,
1014*4e366538SXin Li     0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x10, 0x03, 0x10, 0x00, 0x00, 0x01,
1015*4e366538SXin Li     0x40, 0x8f, 0x26, 0xe8, 0xf4, 0xcc, 0xf9, 0x69, 0x2b, 0x1b, 0x2a, 0xcb,
1016*4e366538SXin Li     0xff, 0xc4, 0x00, 0x1b, 0x10, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00,
1017*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x11,
1018*4e366538SXin Li     0x00, 0x03, 0x10, 0x12, 0x13, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00,
1019*4e366538SXin Li     0x01, 0x05, 0x02, 0x3b, 0x80, 0x6f, 0x56, 0x76, 0x56, 0x23, 0x87, 0x99,
1020*4e366538SXin Li     0x0d, 0x26, 0x62, 0xf6, 0xbf, 0xff, 0xc4, 0x00, 0x19, 0x11, 0x01, 0x00,
1021*4e366538SXin Li     0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022*4e366538SXin Li     0x00, 0x00, 0x01, 0x00, 0x10, 0x11, 0x02, 0x12, 0xff, 0xda, 0x00, 0x08,
1023*4e366538SXin Li     0x01, 0x03, 0x01, 0x01, 0x3f, 0x01, 0xf1, 0x00, 0x27, 0x45, 0xbb, 0x31,
1024*4e366538SXin Li     0xaf, 0xff, 0xc4, 0x00, 0x1a, 0x11, 0x00, 0x02, 0x03, 0x01, 0x01, 0x00,
1025*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1026*4e366538SXin Li     0x02, 0x10, 0x11, 0x41, 0x12, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01,
1027*4e366538SXin Li     0x01, 0x3f, 0x01, 0xf6, 0x4b, 0x5f, 0x48, 0xb3, 0x69, 0x63, 0x35, 0x72,
1028*4e366538SXin Li     0xbf, 0xff, 0xc4, 0x00, 0x1e, 0x10, 0x00, 0x02, 0x01, 0x03, 0x05, 0x00,
1029*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
1030*4e366538SXin Li     0x21, 0x02, 0x12, 0x32, 0x10, 0x31, 0x71, 0x81, 0xa1, 0xff, 0xda, 0x00,
1031*4e366538SXin Li     0x08, 0x01, 0x01, 0x00, 0x06, 0x3f, 0x02, 0x4b, 0xb3, 0x28, 0x32, 0xd2,
1032*4e366538SXin Li     0xed, 0xf9, 0x1d, 0x3e, 0x13, 0x51, 0x73, 0x83, 0xff, 0xc4, 0x00, 0x1c,
1033*4e366538SXin Li     0x10, 0x01, 0x01, 0x01, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
1034*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x21, 0x51, 0x31, 0x61,
1035*4e366538SXin Li     0x81, 0xf0, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x21,
1036*4e366538SXin Li     0x75, 0x6e, 0x31, 0x94, 0x28, 0xf9, 0x30, 0xdc, 0x27, 0xdb, 0xa9, 0x01,
1037*4e366538SXin Li     0xf3, 0xde, 0x02, 0xa0, 0xed, 0x1e, 0x34, 0x68, 0x23, 0xf9, 0xc6, 0x48,
1038*4e366538SXin Li     0x5d, 0x7a, 0x35, 0x02, 0xf5, 0x6f, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01,
1039*4e366538SXin Li     0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x26, 0x61, 0xd4, 0xff,
1040*4e366538SXin Li     0xc4, 0x00, 0x1a, 0x11, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,
1041*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x21,
1042*4e366538SXin Li     0x31, 0x41, 0x51, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f,
1043*4e366538SXin Li     0x10, 0x54, 0xa8, 0xbf, 0x50, 0x87, 0xb0, 0x9d, 0x8b, 0xc4, 0x6a, 0x26,
1044*4e366538SXin Li     0x6b, 0x2a, 0x9c, 0x1f, 0xff, 0xc4, 0x00, 0x18, 0x11, 0x01, 0x01, 0x01,
1045*4e366538SXin Li     0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1046*4e366538SXin Li     0x00, 0x01, 0x00, 0x11, 0x21, 0x51, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02,
1047*4e366538SXin Li     0x01, 0x01, 0x3f, 0x10, 0x70, 0xe1, 0x3e, 0xd1, 0x8e, 0x0d, 0xe1, 0xb5,
1048*4e366538SXin Li     0xd5, 0x91, 0x76, 0x43, 0x82, 0x45, 0x4c, 0x7b, 0x7f, 0xff, 0xc4, 0x00,
1049*4e366538SXin Li     0x1f, 0x10, 0x01, 0x00, 0x02, 0x01, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00,
1050*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x31, 0x41, 0x61,
1051*4e366538SXin Li     0x71, 0x91, 0x21, 0x81, 0xd1, 0xb1, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01,
1052*4e366538SXin Li     0x00, 0x01, 0x3f, 0x10, 0x1b, 0x30, 0xe9, 0x58, 0xbe, 0x1a, 0xfd, 0x8a,
1053*4e366538SXin Li     0xeb, 0x8b, 0x34, 0x74, 0x80, 0x4b, 0xb5, 0xd5, 0xab, 0xcd, 0x46, 0x96,
1054*4e366538SXin Li     0x2e, 0xec, 0xbd, 0xaa, 0x78, 0x47, 0x5c, 0x47, 0xa7, 0x30, 0x49, 0xad,
1055*4e366538SXin Li     0x88, 0x7c, 0x40, 0x74, 0x30, 0xff, 0x00, 0x23, 0x1d, 0x03, 0x0b, 0xb7,
1056*4e366538SXin Li     0xd4, 0xff, 0xd9};
1057*4e366538SXin Li static const size_t kTest1JpgLen = 735;
1058*4e366538SXin Li 
1059*4e366538SXin Li // test 2 is J420
1060*4e366538SXin Li static const uint8_t kTest2Jpg[] = {
1061*4e366538SXin Li     0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
1062*4e366538SXin Li     0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
1063*4e366538SXin Li     0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, 0x0e, 0x12,
1064*4e366538SXin Li     0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23,
1065*4e366538SXin Li     0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40,
1066*4e366538SXin Li     0x48, 0x5c, 0x4e, 0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51,
1067*4e366538SXin Li     0x57, 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64,
1068*4e366538SXin Li     0x78, 0x5c, 0x65, 0x67, 0x63, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x11, 0x12,
1069*4e366538SXin Li     0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42,
1070*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1071*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1072*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1073*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1074*4e366538SXin Li     0x63, 0x63, 0xff, 0xc2, 0x00, 0x11, 0x08, 0x00, 0x10, 0x00, 0x20, 0x03,
1075*4e366538SXin Li     0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
1076*4e366538SXin Li     0x18, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x01, 0x02, 0x04, 0xff,
1078*4e366538SXin Li     0xc4, 0x00, 0x16, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1079*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0xff,
1080*4e366538SXin Li     0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x10, 0x03, 0x10, 0x00, 0x00,
1081*4e366538SXin Li     0x01, 0x20, 0xe7, 0x28, 0xa3, 0x0b, 0x2e, 0x2d, 0xcf, 0xff, 0xc4, 0x00,
1082*4e366538SXin Li     0x1b, 0x10, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
1083*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x11, 0x00, 0x03, 0x10,
1084*4e366538SXin Li     0x12, 0x13, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x05, 0x02,
1085*4e366538SXin Li     0x3b, 0x80, 0x6f, 0x56, 0x76, 0x56, 0x23, 0x87, 0x99, 0x0d, 0x26, 0x62,
1086*4e366538SXin Li     0xf6, 0xbf, 0xff, 0xc4, 0x00, 0x17, 0x11, 0x01, 0x00, 0x03, 0x00, 0x00,
1087*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1088*4e366538SXin Li     0x01, 0x11, 0x21, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f,
1089*4e366538SXin Li     0x01, 0xc8, 0x53, 0xff, 0xc4, 0x00, 0x16, 0x11, 0x01, 0x01, 0x01, 0x00,
1090*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1091*4e366538SXin Li     0x00, 0x11, 0x32, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01, 0x3f,
1092*4e366538SXin Li     0x01, 0xd2, 0xc7, 0xff, 0xc4, 0x00, 0x1e, 0x10, 0x00, 0x02, 0x01, 0x03,
1093*4e366538SXin Li     0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1094*4e366538SXin Li     0x00, 0x11, 0x21, 0x02, 0x12, 0x32, 0x10, 0x31, 0x71, 0x81, 0xa1, 0xff,
1095*4e366538SXin Li     0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x06, 0x3f, 0x02, 0x4b, 0xb3, 0x28,
1096*4e366538SXin Li     0x32, 0xd2, 0xed, 0xf9, 0x1d, 0x3e, 0x13, 0x51, 0x73, 0x83, 0xff, 0xc4,
1097*4e366538SXin Li     0x00, 0x1c, 0x10, 0x01, 0x01, 0x01, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00,
1098*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x21, 0x51,
1099*4e366538SXin Li     0x31, 0x61, 0x81, 0xf0, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01,
1100*4e366538SXin Li     0x3f, 0x21, 0x75, 0x6e, 0x31, 0x94, 0x28, 0xf9, 0x30, 0xdc, 0x27, 0xdb,
1101*4e366538SXin Li     0xa9, 0x01, 0xf3, 0xde, 0x02, 0xa0, 0xed, 0x1e, 0x34, 0x68, 0x23, 0xf9,
1102*4e366538SXin Li     0xc6, 0x48, 0x5d, 0x7a, 0x35, 0x02, 0xf5, 0x6f, 0xff, 0xda, 0x00, 0x0c,
1103*4e366538SXin Li     0x03, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x13, 0x5f,
1104*4e366538SXin Li     0xff, 0xc4, 0x00, 0x17, 0x11, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
1105*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11,
1106*4e366538SXin Li     0x21, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, 0x10, 0x0e,
1107*4e366538SXin Li     0xa1, 0x3a, 0x76, 0xff, 0xc4, 0x00, 0x17, 0x11, 0x01, 0x01, 0x01, 0x01,
1108*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109*4e366538SXin Li     0x01, 0x00, 0x21, 0x11, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01,
1110*4e366538SXin Li     0x3f, 0x10, 0x57, 0x0b, 0x08, 0x70, 0xdb, 0xff, 0xc4, 0x00, 0x1f, 0x10,
1111*4e366538SXin Li     0x01, 0x00, 0x02, 0x01, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1112*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x31, 0x41, 0x61, 0x71, 0x91,
1113*4e366538SXin Li     0x21, 0x81, 0xd1, 0xb1, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01,
1114*4e366538SXin Li     0x3f, 0x10, 0x1b, 0x30, 0xe9, 0x58, 0xbe, 0x1a, 0xfd, 0x8a, 0xeb, 0x8b,
1115*4e366538SXin Li     0x34, 0x74, 0x80, 0x4b, 0xb5, 0xd5, 0xab, 0xcd, 0x46, 0x96, 0x2e, 0xec,
1116*4e366538SXin Li     0xbd, 0xaa, 0x78, 0x47, 0x5c, 0x47, 0xa7, 0x30, 0x49, 0xad, 0x88, 0x7c,
1117*4e366538SXin Li     0x40, 0x74, 0x30, 0xff, 0x00, 0x23, 0x1d, 0x03, 0x0b, 0xb7, 0xd4, 0xff,
1118*4e366538SXin Li     0xd9};
1119*4e366538SXin Li static const size_t kTest2JpgLen = 685;
1120*4e366538SXin Li 
1121*4e366538SXin Li // test 3 is J422
1122*4e366538SXin Li static const uint8_t kTest3Jpg[] = {
1123*4e366538SXin Li     0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
1124*4e366538SXin Li     0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
1125*4e366538SXin Li     0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, 0x0e, 0x12,
1126*4e366538SXin Li     0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23,
1127*4e366538SXin Li     0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40,
1128*4e366538SXin Li     0x48, 0x5c, 0x4e, 0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51,
1129*4e366538SXin Li     0x57, 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64,
1130*4e366538SXin Li     0x78, 0x5c, 0x65, 0x67, 0x63, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x11, 0x12,
1131*4e366538SXin Li     0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42,
1132*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1133*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1134*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1135*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1136*4e366538SXin Li     0x63, 0x63, 0xff, 0xc2, 0x00, 0x11, 0x08, 0x00, 0x10, 0x00, 0x20, 0x03,
1137*4e366538SXin Li     0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
1138*4e366538SXin Li     0x17, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1139*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x01, 0x02, 0xff, 0xc4,
1140*4e366538SXin Li     0x00, 0x17, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0xff,
1142*4e366538SXin Li     0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x10, 0x03, 0x10, 0x00, 0x00,
1143*4e366538SXin Li     0x01, 0x43, 0x8d, 0x1f, 0xa2, 0xb3, 0xca, 0x1b, 0x57, 0x0f, 0xff, 0xc4,
1144*4e366538SXin Li     0x00, 0x1b, 0x10, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00,
1145*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x11, 0x00, 0x03,
1146*4e366538SXin Li     0x10, 0x12, 0x13, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x05,
1147*4e366538SXin Li     0x02, 0x3b, 0x80, 0x6f, 0x56, 0x76, 0x56, 0x23, 0x87, 0x99, 0x0d, 0x26,
1148*4e366538SXin Li     0x62, 0xf6, 0xbf, 0xff, 0xc4, 0x00, 0x19, 0x11, 0x00, 0x02, 0x03, 0x01,
1149*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1150*4e366538SXin Li     0x00, 0x01, 0x02, 0x10, 0x11, 0x21, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03,
1151*4e366538SXin Li     0x01, 0x01, 0x3f, 0x01, 0x51, 0xce, 0x8c, 0x75, 0xff, 0xc4, 0x00, 0x18,
1152*4e366538SXin Li     0x11, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1153*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x61, 0x21, 0xff, 0xda,
1154*4e366538SXin Li     0x00, 0x08, 0x01, 0x02, 0x01, 0x01, 0x3f, 0x01, 0xa6, 0xd9, 0x2f, 0x84,
1155*4e366538SXin Li     0xe8, 0xf0, 0xff, 0xc4, 0x00, 0x1e, 0x10, 0x00, 0x02, 0x01, 0x03, 0x05,
1156*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1157*4e366538SXin Li     0x11, 0x21, 0x02, 0x12, 0x32, 0x10, 0x31, 0x71, 0x81, 0xa1, 0xff, 0xda,
1158*4e366538SXin Li     0x00, 0x08, 0x01, 0x01, 0x00, 0x06, 0x3f, 0x02, 0x4b, 0xb3, 0x28, 0x32,
1159*4e366538SXin Li     0xd2, 0xed, 0xf9, 0x1d, 0x3e, 0x13, 0x51, 0x73, 0x83, 0xff, 0xc4, 0x00,
1160*4e366538SXin Li     0x1c, 0x10, 0x01, 0x01, 0x01, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00,
1161*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x21, 0x51, 0x31,
1162*4e366538SXin Li     0x61, 0x81, 0xf0, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f,
1163*4e366538SXin Li     0x21, 0x75, 0x6e, 0x31, 0x94, 0x28, 0xf9, 0x30, 0xdc, 0x27, 0xdb, 0xa9,
1164*4e366538SXin Li     0x01, 0xf3, 0xde, 0x02, 0xa0, 0xed, 0x1e, 0x34, 0x68, 0x23, 0xf9, 0xc6,
1165*4e366538SXin Li     0x48, 0x5d, 0x7a, 0x35, 0x02, 0xf5, 0x6f, 0xff, 0xda, 0x00, 0x0c, 0x03,
1166*4e366538SXin Li     0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x2e, 0x45, 0xff,
1167*4e366538SXin Li     0xc4, 0x00, 0x18, 0x11, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
1168*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x21,
1169*4e366538SXin Li     0x31, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, 0x10, 0x53,
1170*4e366538SXin Li     0x50, 0xba, 0x54, 0xc1, 0x67, 0x4f, 0xff, 0xc4, 0x00, 0x18, 0x11, 0x00,
1171*4e366538SXin Li     0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1172*4e366538SXin Li     0x00, 0x00, 0x00, 0x01, 0x11, 0x21, 0x00, 0x10, 0xff, 0xda, 0x00, 0x08,
1173*4e366538SXin Li     0x01, 0x02, 0x01, 0x01, 0x3f, 0x10, 0x18, 0x81, 0x5c, 0x04, 0x1a, 0xca,
1174*4e366538SXin Li     0x91, 0xbf, 0xff, 0xc4, 0x00, 0x1f, 0x10, 0x01, 0x00, 0x02, 0x01, 0x04,
1175*4e366538SXin Li     0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1176*4e366538SXin Li     0x00, 0x11, 0x31, 0x41, 0x61, 0x71, 0x91, 0x21, 0x81, 0xd1, 0xb1, 0xff,
1177*4e366538SXin Li     0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x10, 0x1b, 0x30, 0xe9,
1178*4e366538SXin Li     0x58, 0xbe, 0x1a, 0xfd, 0x8a, 0xeb, 0x8b, 0x34, 0x74, 0x80, 0x4b, 0xb5,
1179*4e366538SXin Li     0xd5, 0xab, 0xcd, 0x46, 0x96, 0x2e, 0xec, 0xbd, 0xaa, 0x78, 0x47, 0x5c,
1180*4e366538SXin Li     0x47, 0xa7, 0x30, 0x49, 0xad, 0x88, 0x7c, 0x40, 0x74, 0x30, 0xff, 0x00,
1181*4e366538SXin Li     0x23, 0x1d, 0x03, 0x0b, 0xb7, 0xd4, 0xff, 0xd9};
1182*4e366538SXin Li static const size_t kTest3JpgLen = 704;
1183*4e366538SXin Li 
1184*4e366538SXin Li // test 4 is J422 vertical - not supported
1185*4e366538SXin Li static const uint8_t kTest4Jpg[] = {
1186*4e366538SXin Li     0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
1187*4e366538SXin Li     0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
1188*4e366538SXin Li     0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, 0x0e, 0x12,
1189*4e366538SXin Li     0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23,
1190*4e366538SXin Li     0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40,
1191*4e366538SXin Li     0x48, 0x5c, 0x4e, 0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51,
1192*4e366538SXin Li     0x57, 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64,
1193*4e366538SXin Li     0x78, 0x5c, 0x65, 0x67, 0x63, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x11, 0x12,
1194*4e366538SXin Li     0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42,
1195*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1196*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1197*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1198*4e366538SXin Li     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1199*4e366538SXin Li     0x63, 0x63, 0xff, 0xc2, 0x00, 0x11, 0x08, 0x00, 0x10, 0x00, 0x20, 0x03,
1200*4e366538SXin Li     0x01, 0x12, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
1201*4e366538SXin Li     0x18, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1202*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x01, 0x02, 0x03, 0xff,
1203*4e366538SXin Li     0xc4, 0x00, 0x16, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1204*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0xff,
1205*4e366538SXin Li     0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x10, 0x03, 0x10, 0x00, 0x00,
1206*4e366538SXin Li     0x01, 0xd2, 0x98, 0xe9, 0x03, 0x0c, 0x00, 0x46, 0x21, 0xd9, 0xff, 0xc4,
1207*4e366538SXin Li     0x00, 0x1b, 0x10, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00,
1208*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x11, 0x00, 0x03,
1209*4e366538SXin Li     0x10, 0x12, 0x13, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x05,
1210*4e366538SXin Li     0x02, 0x3b, 0x80, 0x6f, 0x56, 0x76, 0x56, 0x23, 0x87, 0x99, 0x0d, 0x26,
1211*4e366538SXin Li     0x62, 0xf6, 0xbf, 0xff, 0xc4, 0x00, 0x17, 0x11, 0x01, 0x01, 0x01, 0x01,
1212*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1213*4e366538SXin Li     0x00, 0x11, 0x01, 0x21, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01,
1214*4e366538SXin Li     0x3f, 0x01, 0x98, 0xb1, 0xbd, 0x47, 0xff, 0xc4, 0x00, 0x18, 0x11, 0x00,
1215*4e366538SXin Li     0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1216*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x11, 0x21, 0xff, 0xda, 0x00, 0x08,
1217*4e366538SXin Li     0x01, 0x02, 0x01, 0x01, 0x3f, 0x01, 0xb6, 0x35, 0xa2, 0xe1, 0x47, 0xff,
1218*4e366538SXin Li     0xc4, 0x00, 0x1e, 0x10, 0x00, 0x02, 0x01, 0x03, 0x05, 0x00, 0x00, 0x00,
1219*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x21, 0x02,
1220*4e366538SXin Li     0x12, 0x32, 0x10, 0x31, 0x71, 0x81, 0xa1, 0xff, 0xda, 0x00, 0x08, 0x01,
1221*4e366538SXin Li     0x01, 0x00, 0x06, 0x3f, 0x02, 0x4b, 0xb3, 0x28, 0x32, 0xd2, 0xed, 0xf9,
1222*4e366538SXin Li     0x1d, 0x3e, 0x13, 0x51, 0x73, 0x83, 0xff, 0xc4, 0x00, 0x1c, 0x10, 0x01,
1223*4e366538SXin Li     0x01, 0x01, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1224*4e366538SXin Li     0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x21, 0x51, 0x31, 0x61, 0x81, 0xf0,
1225*4e366538SXin Li     0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x21, 0x75, 0x6e,
1226*4e366538SXin Li     0x31, 0x94, 0x28, 0xf9, 0x30, 0xdc, 0x27, 0xdb, 0xa9, 0x01, 0xf3, 0xde,
1227*4e366538SXin Li     0x02, 0xa0, 0xed, 0x1e, 0x34, 0x68, 0x23, 0xf9, 0xc6, 0x48, 0x5d, 0x7a,
1228*4e366538SXin Li     0x35, 0x02, 0xf5, 0x6f, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
1229*4e366538SXin Li     0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x24, 0xaf, 0xff, 0xc4, 0x00, 0x19,
1230*4e366538SXin Li     0x11, 0x00, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x51, 0x21, 0x31, 0xff,
1232*4e366538SXin Li     0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, 0x10, 0x59, 0x11, 0xca,
1233*4e366538SXin Li     0x42, 0x60, 0x9f, 0x69, 0xff, 0xc4, 0x00, 0x19, 0x11, 0x00, 0x02, 0x03,
1234*4e366538SXin Li     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235*4e366538SXin Li     0x00, 0x00, 0x01, 0x11, 0x21, 0x31, 0x61, 0xff, 0xda, 0x00, 0x08, 0x01,
1236*4e366538SXin Li     0x02, 0x01, 0x01, 0x3f, 0x10, 0xb0, 0xd7, 0x27, 0x51, 0xb6, 0x41, 0xff,
1237*4e366538SXin Li     0xc4, 0x00, 0x1f, 0x10, 0x01, 0x00, 0x02, 0x01, 0x04, 0x03, 0x01, 0x00,
1238*4e366538SXin Li     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x31,
1239*4e366538SXin Li     0x41, 0x61, 0x71, 0x91, 0x21, 0x81, 0xd1, 0xb1, 0xff, 0xda, 0x00, 0x08,
1240*4e366538SXin Li     0x01, 0x01, 0x00, 0x01, 0x3f, 0x10, 0x1b, 0x30, 0xe9, 0x58, 0xbe, 0x1a,
1241*4e366538SXin Li     0xfd, 0x8a, 0xeb, 0x8b, 0x34, 0x74, 0x80, 0x4b, 0xb5, 0xd5, 0xab, 0xcd,
1242*4e366538SXin Li     0x46, 0x96, 0x2e, 0xec, 0xbd, 0xaa, 0x78, 0x47, 0x5c, 0x47, 0xa7, 0x30,
1243*4e366538SXin Li     0x49, 0xad, 0x88, 0x7c, 0x40, 0x74, 0x30, 0xff, 0x00, 0x23, 0x1d, 0x03,
1244*4e366538SXin Li     0x0b, 0xb7, 0xd4, 0xff, 0xd9};
1245*4e366538SXin Li static const size_t kTest4JpgLen = 701;
1246*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGSize)1247*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGSize) {
1248*4e366538SXin Li   int width = 0;
1249*4e366538SXin Li   int height = 0;
1250*4e366538SXin Li   int ret = MJPGSize(kTest2Jpg, kTest2JpgLen, &width, &height);
1251*4e366538SXin Li   EXPECT_EQ(0, ret);
1252*4e366538SXin Li 
1253*4e366538SXin Li   printf("test jpeg size %d x %d\n", width, height);
1254*4e366538SXin Li }
1255*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToI420)1256*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToI420) {
1257*4e366538SXin Li   int width = 0;
1258*4e366538SXin Li   int height = 0;
1259*4e366538SXin Li   int ret = MJPGSize(kTest2Jpg, kTest2JpgLen, &width, &height);
1260*4e366538SXin Li   EXPECT_EQ(0, ret);
1261*4e366538SXin Li 
1262*4e366538SXin Li   int half_width = (width + 1) / 2;
1263*4e366538SXin Li   int half_height = (height + 1) / 2;
1264*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1265*4e366538SXin Li                              benchmark_height_ / (width * height);
1266*4e366538SXin Li   if (benchmark_iterations < 1) {
1267*4e366538SXin Li     benchmark_iterations = 1;
1268*4e366538SXin Li   }
1269*4e366538SXin Li 
1270*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1271*4e366538SXin Li   align_buffer_page_end(dst_u, half_width * half_height);
1272*4e366538SXin Li   align_buffer_page_end(dst_v, half_width * half_height);
1273*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1274*4e366538SXin Li     ret = MJPGToI420(kTest2Jpg, kTest2JpgLen, dst_y, width, dst_u, half_width,
1275*4e366538SXin Li                      dst_v, half_width, width, height, width, height);
1276*4e366538SXin Li   }
1277*4e366538SXin Li   // Expect sucesss
1278*4e366538SXin Li   EXPECT_EQ(0, ret);
1279*4e366538SXin Li 
1280*4e366538SXin Li   // Test result matches known hash value.
1281*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1282*4e366538SXin Li   uint32_t dst_u_hash = HashDjb2(dst_u, half_width * half_height, 5381);
1283*4e366538SXin Li   uint32_t dst_v_hash = HashDjb2(dst_v, half_width * half_height, 5381);
1284*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 2682851208u);
1285*4e366538SXin Li   EXPECT_EQ(dst_u_hash, 2501859930u);
1286*4e366538SXin Li   EXPECT_EQ(dst_v_hash, 2126459123u);
1287*4e366538SXin Li 
1288*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1289*4e366538SXin Li   free_aligned_buffer_page_end(dst_u);
1290*4e366538SXin Li   free_aligned_buffer_page_end(dst_v);
1291*4e366538SXin Li }
1292*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToI420_NV21)1293*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToI420_NV21) {
1294*4e366538SXin Li   int width = 0;
1295*4e366538SXin Li   int height = 0;
1296*4e366538SXin Li   int ret = MJPGSize(kTest2Jpg, kTest2JpgLen, &width, &height);
1297*4e366538SXin Li   EXPECT_EQ(0, ret);
1298*4e366538SXin Li 
1299*4e366538SXin Li   int half_width = (width + 1) / 2;
1300*4e366538SXin Li   int half_height = (height + 1) / 2;
1301*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1302*4e366538SXin Li                              benchmark_height_ / (width * height);
1303*4e366538SXin Li   if (benchmark_iterations < 1) {
1304*4e366538SXin Li     benchmark_iterations = 1;
1305*4e366538SXin Li   }
1306*4e366538SXin Li 
1307*4e366538SXin Li   // Convert to NV21
1308*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1309*4e366538SXin Li   align_buffer_page_end(dst_vu, half_width * half_height * 2);
1310*4e366538SXin Li 
1311*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1312*4e366538SXin Li     ret = MJPGToNV21(kTest2Jpg, kTest2JpgLen, dst_y, width, dst_vu,
1313*4e366538SXin Li                      half_width * 2, width, height, width, height);
1314*4e366538SXin Li   }
1315*4e366538SXin Li   // Expect sucesss
1316*4e366538SXin Li   EXPECT_EQ(0, ret);
1317*4e366538SXin Li 
1318*4e366538SXin Li   // Convert to I420
1319*4e366538SXin Li   align_buffer_page_end(dst2_y, width * height);
1320*4e366538SXin Li   align_buffer_page_end(dst2_u, half_width * half_height);
1321*4e366538SXin Li   align_buffer_page_end(dst2_v, half_width * half_height);
1322*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1323*4e366538SXin Li     ret = MJPGToI420(kTest2Jpg, kTest2JpgLen, dst2_y, width, dst2_u, half_width,
1324*4e366538SXin Li                      dst2_v, half_width, width, height, width, height);
1325*4e366538SXin Li   }
1326*4e366538SXin Li   // Expect sucesss
1327*4e366538SXin Li   EXPECT_EQ(0, ret);
1328*4e366538SXin Li 
1329*4e366538SXin Li   // Convert I420 to NV21
1330*4e366538SXin Li   align_buffer_page_end(dst3_y, width * height);
1331*4e366538SXin Li   align_buffer_page_end(dst3_vu, half_width * half_height * 2);
1332*4e366538SXin Li 
1333*4e366538SXin Li   I420ToNV21(dst2_y, width, dst2_u, half_width, dst2_v, half_width, dst3_y,
1334*4e366538SXin Li              width, dst3_vu, half_width * 2, width, height);
1335*4e366538SXin Li 
1336*4e366538SXin Li   for (int i = 0; i < width * height; ++i) {
1337*4e366538SXin Li     EXPECT_EQ(dst_y[i], dst3_y[i]);
1338*4e366538SXin Li   }
1339*4e366538SXin Li   for (int i = 0; i < half_width * half_height * 2; ++i) {
1340*4e366538SXin Li     EXPECT_EQ(dst_vu[i], dst3_vu[i]);
1341*4e366538SXin Li     EXPECT_EQ(dst_vu[i], dst3_vu[i]);
1342*4e366538SXin Li   }
1343*4e366538SXin Li 
1344*4e366538SXin Li   free_aligned_buffer_page_end(dst3_y);
1345*4e366538SXin Li   free_aligned_buffer_page_end(dst3_vu);
1346*4e366538SXin Li 
1347*4e366538SXin Li   free_aligned_buffer_page_end(dst2_y);
1348*4e366538SXin Li   free_aligned_buffer_page_end(dst2_u);
1349*4e366538SXin Li   free_aligned_buffer_page_end(dst2_v);
1350*4e366538SXin Li 
1351*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1352*4e366538SXin Li   free_aligned_buffer_page_end(dst_vu);
1353*4e366538SXin Li }
1354*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToI420_NV12)1355*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToI420_NV12) {
1356*4e366538SXin Li   int width = 0;
1357*4e366538SXin Li   int height = 0;
1358*4e366538SXin Li   int ret = MJPGSize(kTest2Jpg, kTest2JpgLen, &width, &height);
1359*4e366538SXin Li   EXPECT_EQ(0, ret);
1360*4e366538SXin Li 
1361*4e366538SXin Li   int half_width = (width + 1) / 2;
1362*4e366538SXin Li   int half_height = (height + 1) / 2;
1363*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1364*4e366538SXin Li                              benchmark_height_ / (width * height);
1365*4e366538SXin Li   if (benchmark_iterations < 1) {
1366*4e366538SXin Li     benchmark_iterations = 1;
1367*4e366538SXin Li   }
1368*4e366538SXin Li 
1369*4e366538SXin Li   // Convert to NV12
1370*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1371*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1372*4e366538SXin Li 
1373*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1374*4e366538SXin Li     ret = MJPGToNV12(kTest2Jpg, kTest2JpgLen, dst_y, width, dst_uv,
1375*4e366538SXin Li                      half_width * 2, width, height, width, height);
1376*4e366538SXin Li   }
1377*4e366538SXin Li   // Expect sucesss
1378*4e366538SXin Li   EXPECT_EQ(0, ret);
1379*4e366538SXin Li 
1380*4e366538SXin Li   // Convert to I420
1381*4e366538SXin Li   align_buffer_page_end(dst2_y, width * height);
1382*4e366538SXin Li   align_buffer_page_end(dst2_u, half_width * half_height);
1383*4e366538SXin Li   align_buffer_page_end(dst2_v, half_width * half_height);
1384*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1385*4e366538SXin Li     ret = MJPGToI420(kTest2Jpg, kTest2JpgLen, dst2_y, width, dst2_u, half_width,
1386*4e366538SXin Li                      dst2_v, half_width, width, height, width, height);
1387*4e366538SXin Li   }
1388*4e366538SXin Li   // Expect sucesss
1389*4e366538SXin Li   EXPECT_EQ(0, ret);
1390*4e366538SXin Li 
1391*4e366538SXin Li   // Convert I420 to NV12
1392*4e366538SXin Li   align_buffer_page_end(dst3_y, width * height);
1393*4e366538SXin Li   align_buffer_page_end(dst3_uv, half_width * half_height * 2);
1394*4e366538SXin Li 
1395*4e366538SXin Li   I420ToNV12(dst2_y, width, dst2_u, half_width, dst2_v, half_width, dst3_y,
1396*4e366538SXin Li              width, dst3_uv, half_width * 2, width, height);
1397*4e366538SXin Li 
1398*4e366538SXin Li   for (int i = 0; i < width * height; ++i) {
1399*4e366538SXin Li     EXPECT_EQ(dst_y[i], dst3_y[i]);
1400*4e366538SXin Li   }
1401*4e366538SXin Li   for (int i = 0; i < half_width * half_height * 2; ++i) {
1402*4e366538SXin Li     EXPECT_EQ(dst_uv[i], dst3_uv[i]);
1403*4e366538SXin Li     EXPECT_EQ(dst_uv[i], dst3_uv[i]);
1404*4e366538SXin Li   }
1405*4e366538SXin Li 
1406*4e366538SXin Li   free_aligned_buffer_page_end(dst3_y);
1407*4e366538SXin Li   free_aligned_buffer_page_end(dst3_uv);
1408*4e366538SXin Li 
1409*4e366538SXin Li   free_aligned_buffer_page_end(dst2_y);
1410*4e366538SXin Li   free_aligned_buffer_page_end(dst2_u);
1411*4e366538SXin Li   free_aligned_buffer_page_end(dst2_v);
1412*4e366538SXin Li 
1413*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1414*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1415*4e366538SXin Li }
1416*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToNV21_420)1417*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToNV21_420) {
1418*4e366538SXin Li   int width = 0;
1419*4e366538SXin Li   int height = 0;
1420*4e366538SXin Li   int ret = MJPGSize(kTest2Jpg, kTest2JpgLen, &width, &height);
1421*4e366538SXin Li   EXPECT_EQ(0, ret);
1422*4e366538SXin Li 
1423*4e366538SXin Li   int half_width = (width + 1) / 2;
1424*4e366538SXin Li   int half_height = (height + 1) / 2;
1425*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1426*4e366538SXin Li                              benchmark_height_ / (width * height);
1427*4e366538SXin Li   if (benchmark_iterations < 1) {
1428*4e366538SXin Li     benchmark_iterations = 1;
1429*4e366538SXin Li   }
1430*4e366538SXin Li 
1431*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1432*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1433*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1434*4e366538SXin Li     ret = MJPGToNV21(kTest2Jpg, kTest2JpgLen, dst_y, width, dst_uv,
1435*4e366538SXin Li                      half_width * 2, width, height, width, height);
1436*4e366538SXin Li   }
1437*4e366538SXin Li   // Expect sucesss
1438*4e366538SXin Li   EXPECT_EQ(0, ret);
1439*4e366538SXin Li 
1440*4e366538SXin Li   // Test result matches known hash value.
1441*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1442*4e366538SXin Li   uint32_t dst_uv_hash = HashDjb2(dst_uv, half_width * half_height * 2, 5381);
1443*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 2682851208u);
1444*4e366538SXin Li   EXPECT_EQ(dst_uv_hash, 1069662856u);
1445*4e366538SXin Li 
1446*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1447*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1448*4e366538SXin Li }
1449*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToNV12_420)1450*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToNV12_420) {
1451*4e366538SXin Li   int width = 0;
1452*4e366538SXin Li   int height = 0;
1453*4e366538SXin Li   int ret = MJPGSize(kTest2Jpg, kTest2JpgLen, &width, &height);
1454*4e366538SXin Li   EXPECT_EQ(0, ret);
1455*4e366538SXin Li 
1456*4e366538SXin Li   int half_width = (width + 1) / 2;
1457*4e366538SXin Li   int half_height = (height + 1) / 2;
1458*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1459*4e366538SXin Li                              benchmark_height_ / (width * height);
1460*4e366538SXin Li   if (benchmark_iterations < 1) {
1461*4e366538SXin Li     benchmark_iterations = 1;
1462*4e366538SXin Li   }
1463*4e366538SXin Li 
1464*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1465*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1466*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1467*4e366538SXin Li     ret = MJPGToNV12(kTest2Jpg, kTest2JpgLen, dst_y, width, dst_uv,
1468*4e366538SXin Li                      half_width * 2, width, height, width, height);
1469*4e366538SXin Li   }
1470*4e366538SXin Li   // Expect sucesss
1471*4e366538SXin Li   EXPECT_EQ(0, ret);
1472*4e366538SXin Li 
1473*4e366538SXin Li   // Test result matches known hash value. Hashes are for VU so flip the plane.
1474*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1475*4e366538SXin Li   align_buffer_page_end(dst_vu, half_width * half_height * 2);
1476*4e366538SXin Li   SwapUVPlane(dst_uv, half_width * 2, dst_vu, half_width * 2, half_width,
1477*4e366538SXin Li               half_height);
1478*4e366538SXin Li   uint32_t dst_vu_hash = HashDjb2(dst_vu, half_width * half_height * 2, 5381);
1479*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 2682851208u);
1480*4e366538SXin Li   EXPECT_EQ(dst_vu_hash, 1069662856u);
1481*4e366538SXin Li 
1482*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1483*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1484*4e366538SXin Li   free_aligned_buffer_page_end(dst_vu);
1485*4e366538SXin Li }
1486*4e366538SXin Li 
1487*4e366538SXin Li // TODO(fbarchard): Improve test to compare against I422, not checksum
TEST_F(LibYUVConvertTest,DISABLED_TestMJPGToNV21_422)1488*4e366538SXin Li TEST_F(LibYUVConvertTest, DISABLED_TestMJPGToNV21_422) {
1489*4e366538SXin Li   int width = 0;
1490*4e366538SXin Li   int height = 0;
1491*4e366538SXin Li   int ret = MJPGSize(kTest3Jpg, kTest3JpgLen, &width, &height);
1492*4e366538SXin Li   EXPECT_EQ(0, ret);
1493*4e366538SXin Li 
1494*4e366538SXin Li   int half_width = (width + 1) / 2;
1495*4e366538SXin Li   int half_height = (height + 1) / 2;
1496*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1497*4e366538SXin Li                              benchmark_height_ / (width * height);
1498*4e366538SXin Li   if (benchmark_iterations < 1) {
1499*4e366538SXin Li     benchmark_iterations = 1;
1500*4e366538SXin Li   }
1501*4e366538SXin Li 
1502*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1503*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1504*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1505*4e366538SXin Li     ret = MJPGToNV21(kTest3Jpg, kTest3JpgLen, dst_y, width, dst_uv,
1506*4e366538SXin Li                      half_width * 2, width, height, width, height);
1507*4e366538SXin Li   }
1508*4e366538SXin Li   // Expect sucesss
1509*4e366538SXin Li   EXPECT_EQ(0, ret);
1510*4e366538SXin Li 
1511*4e366538SXin Li   // Test result matches known hash value.
1512*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1513*4e366538SXin Li   uint32_t dst_uv_hash = HashDjb2(dst_uv, half_width * half_height * 2, 5381);
1514*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 2682851208u);
1515*4e366538SXin Li   EXPECT_EQ(dst_uv_hash, 493520167u);
1516*4e366538SXin Li 
1517*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1518*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1519*4e366538SXin Li }
1520*4e366538SXin Li 
TEST_F(LibYUVConvertTest,DISABLED_TestMJPGToNV12_422)1521*4e366538SXin Li TEST_F(LibYUVConvertTest, DISABLED_TestMJPGToNV12_422) {
1522*4e366538SXin Li   int width = 0;
1523*4e366538SXin Li   int height = 0;
1524*4e366538SXin Li   int ret = MJPGSize(kTest3Jpg, kTest3JpgLen, &width, &height);
1525*4e366538SXin Li   EXPECT_EQ(0, ret);
1526*4e366538SXin Li 
1527*4e366538SXin Li   int half_width = (width + 1) / 2;
1528*4e366538SXin Li   int half_height = (height + 1) / 2;
1529*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1530*4e366538SXin Li                              benchmark_height_ / (width * height);
1531*4e366538SXin Li   if (benchmark_iterations < 1) {
1532*4e366538SXin Li     benchmark_iterations = 1;
1533*4e366538SXin Li   }
1534*4e366538SXin Li 
1535*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1536*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1537*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1538*4e366538SXin Li     ret = MJPGToNV12(kTest3Jpg, kTest3JpgLen, dst_y, width, dst_uv,
1539*4e366538SXin Li                      half_width * 2, width, height, width, height);
1540*4e366538SXin Li   }
1541*4e366538SXin Li   // Expect sucesss
1542*4e366538SXin Li   EXPECT_EQ(0, ret);
1543*4e366538SXin Li 
1544*4e366538SXin Li   // Test result matches known hash value. Hashes are for VU so flip the plane.
1545*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1546*4e366538SXin Li   align_buffer_page_end(dst_vu, half_width * half_height * 2);
1547*4e366538SXin Li   SwapUVPlane(dst_uv, half_width * 2, dst_vu, half_width * 2, half_width,
1548*4e366538SXin Li               half_height);
1549*4e366538SXin Li   uint32_t dst_vu_hash = HashDjb2(dst_vu, half_width * half_height * 2, 5381);
1550*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 2682851208u);
1551*4e366538SXin Li   EXPECT_EQ(dst_vu_hash, 493520167u);
1552*4e366538SXin Li 
1553*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1554*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1555*4e366538SXin Li   free_aligned_buffer_page_end(dst_vu);
1556*4e366538SXin Li }
1557*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToNV21_400)1558*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToNV21_400) {
1559*4e366538SXin Li   int width = 0;
1560*4e366538SXin Li   int height = 0;
1561*4e366538SXin Li   int ret = MJPGSize(kTest0Jpg, kTest0JpgLen, &width, &height);
1562*4e366538SXin Li   EXPECT_EQ(0, ret);
1563*4e366538SXin Li 
1564*4e366538SXin Li   int half_width = (width + 1) / 2;
1565*4e366538SXin Li   int half_height = (height + 1) / 2;
1566*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1567*4e366538SXin Li                              benchmark_height_ / (width * height);
1568*4e366538SXin Li   if (benchmark_iterations < 1) {
1569*4e366538SXin Li     benchmark_iterations = 1;
1570*4e366538SXin Li   }
1571*4e366538SXin Li 
1572*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1573*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1574*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1575*4e366538SXin Li     ret = MJPGToNV21(kTest0Jpg, kTest0JpgLen, dst_y, width, dst_uv,
1576*4e366538SXin Li                      half_width * 2, width, height, width, height);
1577*4e366538SXin Li   }
1578*4e366538SXin Li   // Expect sucesss
1579*4e366538SXin Li   EXPECT_EQ(0, ret);
1580*4e366538SXin Li 
1581*4e366538SXin Li   // Test result matches known hash value.
1582*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1583*4e366538SXin Li   uint32_t dst_uv_hash = HashDjb2(dst_uv, half_width * half_height * 2, 5381);
1584*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 330644005u);
1585*4e366538SXin Li   EXPECT_EQ(dst_uv_hash, 135214341u);
1586*4e366538SXin Li 
1587*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1588*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1589*4e366538SXin Li }
1590*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToNV12_400)1591*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToNV12_400) {
1592*4e366538SXin Li   int width = 0;
1593*4e366538SXin Li   int height = 0;
1594*4e366538SXin Li   int ret = MJPGSize(kTest0Jpg, kTest0JpgLen, &width, &height);
1595*4e366538SXin Li   EXPECT_EQ(0, ret);
1596*4e366538SXin Li 
1597*4e366538SXin Li   int half_width = (width + 1) / 2;
1598*4e366538SXin Li   int half_height = (height + 1) / 2;
1599*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1600*4e366538SXin Li                              benchmark_height_ / (width * height);
1601*4e366538SXin Li   if (benchmark_iterations < 1) {
1602*4e366538SXin Li     benchmark_iterations = 1;
1603*4e366538SXin Li   }
1604*4e366538SXin Li 
1605*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1606*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1607*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1608*4e366538SXin Li     ret = MJPGToNV12(kTest0Jpg, kTest0JpgLen, dst_y, width, dst_uv,
1609*4e366538SXin Li                      half_width * 2, width, height, width, height);
1610*4e366538SXin Li   }
1611*4e366538SXin Li   // Expect sucesss
1612*4e366538SXin Li   EXPECT_EQ(0, ret);
1613*4e366538SXin Li 
1614*4e366538SXin Li   // Test result matches known hash value. Hashes are for VU so flip the plane.
1615*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1616*4e366538SXin Li   align_buffer_page_end(dst_vu, half_width * half_height * 2);
1617*4e366538SXin Li   SwapUVPlane(dst_uv, half_width * 2, dst_vu, half_width * 2, half_width,
1618*4e366538SXin Li               half_height);
1619*4e366538SXin Li   uint32_t dst_vu_hash = HashDjb2(dst_vu, half_width * half_height * 2, 5381);
1620*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 330644005u);
1621*4e366538SXin Li   EXPECT_EQ(dst_vu_hash, 135214341u);
1622*4e366538SXin Li 
1623*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1624*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1625*4e366538SXin Li   free_aligned_buffer_page_end(dst_vu);
1626*4e366538SXin Li }
1627*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToNV21_444)1628*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToNV21_444) {
1629*4e366538SXin Li   int width = 0;
1630*4e366538SXin Li   int height = 0;
1631*4e366538SXin Li   int ret = MJPGSize(kTest1Jpg, kTest1JpgLen, &width, &height);
1632*4e366538SXin Li   EXPECT_EQ(0, ret);
1633*4e366538SXin Li 
1634*4e366538SXin Li   int half_width = (width + 1) / 2;
1635*4e366538SXin Li   int half_height = (height + 1) / 2;
1636*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1637*4e366538SXin Li                              benchmark_height_ / (width * height);
1638*4e366538SXin Li   if (benchmark_iterations < 1) {
1639*4e366538SXin Li     benchmark_iterations = 1;
1640*4e366538SXin Li   }
1641*4e366538SXin Li 
1642*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1643*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1644*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1645*4e366538SXin Li     ret = MJPGToNV21(kTest1Jpg, kTest1JpgLen, dst_y, width, dst_uv,
1646*4e366538SXin Li                      half_width * 2, width, height, width, height);
1647*4e366538SXin Li   }
1648*4e366538SXin Li   // Expect sucesss
1649*4e366538SXin Li   EXPECT_EQ(0, ret);
1650*4e366538SXin Li 
1651*4e366538SXin Li   // Test result matches known hash value.
1652*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1653*4e366538SXin Li   uint32_t dst_uv_hash = HashDjb2(dst_uv, half_width * half_height * 2, 5381);
1654*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 2682851208u);
1655*4e366538SXin Li   EXPECT_EQ(dst_uv_hash, 506143297u);
1656*4e366538SXin Li 
1657*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1658*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1659*4e366538SXin Li }
1660*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToNV12_444)1661*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToNV12_444) {
1662*4e366538SXin Li   int width = 0;
1663*4e366538SXin Li   int height = 0;
1664*4e366538SXin Li   int ret = MJPGSize(kTest1Jpg, kTest1JpgLen, &width, &height);
1665*4e366538SXin Li   EXPECT_EQ(0, ret);
1666*4e366538SXin Li 
1667*4e366538SXin Li   int half_width = (width + 1) / 2;
1668*4e366538SXin Li   int half_height = (height + 1) / 2;
1669*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1670*4e366538SXin Li                              benchmark_height_ / (width * height);
1671*4e366538SXin Li   if (benchmark_iterations < 1) {
1672*4e366538SXin Li     benchmark_iterations = 1;
1673*4e366538SXin Li   }
1674*4e366538SXin Li 
1675*4e366538SXin Li   align_buffer_page_end(dst_y, width * height);
1676*4e366538SXin Li   align_buffer_page_end(dst_uv, half_width * half_height * 2);
1677*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1678*4e366538SXin Li     ret = MJPGToNV12(kTest1Jpg, kTest1JpgLen, dst_y, width, dst_uv,
1679*4e366538SXin Li                      half_width * 2, width, height, width, height);
1680*4e366538SXin Li   }
1681*4e366538SXin Li   // Expect sucesss
1682*4e366538SXin Li   EXPECT_EQ(0, ret);
1683*4e366538SXin Li 
1684*4e366538SXin Li   // Test result matches known hash value. Hashes are for VU so flip the plane.
1685*4e366538SXin Li   uint32_t dst_y_hash = HashDjb2(dst_y, width * height, 5381);
1686*4e366538SXin Li   align_buffer_page_end(dst_vu, half_width * half_height * 2);
1687*4e366538SXin Li   SwapUVPlane(dst_uv, half_width * 2, dst_vu, half_width * 2, half_width,
1688*4e366538SXin Li               half_height);
1689*4e366538SXin Li   uint32_t dst_vu_hash = HashDjb2(dst_vu, half_width * half_height * 2, 5381);
1690*4e366538SXin Li   EXPECT_EQ(dst_y_hash, 2682851208u);
1691*4e366538SXin Li   EXPECT_EQ(dst_vu_hash, 506143297u);
1692*4e366538SXin Li 
1693*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1694*4e366538SXin Li   free_aligned_buffer_page_end(dst_uv);
1695*4e366538SXin Li   free_aligned_buffer_page_end(dst_vu);
1696*4e366538SXin Li }
1697*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGToARGB)1698*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGToARGB) {
1699*4e366538SXin Li   int width = 0;
1700*4e366538SXin Li   int height = 0;
1701*4e366538SXin Li   int ret = MJPGSize(kTest3Jpg, kTest3JpgLen, &width, &height);
1702*4e366538SXin Li   EXPECT_EQ(0, ret);
1703*4e366538SXin Li 
1704*4e366538SXin Li   int benchmark_iterations = benchmark_iterations_ * benchmark_width_ *
1705*4e366538SXin Li                              benchmark_height_ / (width * height);
1706*4e366538SXin Li   if (benchmark_iterations < 1) {
1707*4e366538SXin Li     benchmark_iterations = 1;
1708*4e366538SXin Li   }
1709*4e366538SXin Li 
1710*4e366538SXin Li   align_buffer_page_end(dst_argb, width * height * 4);
1711*4e366538SXin Li   for (int times = 0; times < benchmark_iterations; ++times) {
1712*4e366538SXin Li     ret = MJPGToARGB(kTest3Jpg, kTest3JpgLen, dst_argb, width * 4, width,
1713*4e366538SXin Li                      height, width, height);
1714*4e366538SXin Li   }
1715*4e366538SXin Li   // Expect sucesss
1716*4e366538SXin Li   EXPECT_EQ(0, ret);
1717*4e366538SXin Li 
1718*4e366538SXin Li   // Test result matches known hash value.
1719*4e366538SXin Li   uint32_t dst_argb_hash = HashDjb2(dst_argb, width * height, 5381);
1720*4e366538SXin Li #ifdef LIBYUV_UNLIMITED_DATA
1721*4e366538SXin Li   EXPECT_EQ(dst_argb_hash, 3900633302u);
1722*4e366538SXin Li #else
1723*4e366538SXin Li   EXPECT_EQ(dst_argb_hash, 2355976473u);
1724*4e366538SXin Li #endif
1725*4e366538SXin Li 
1726*4e366538SXin Li   free_aligned_buffer_page_end(dst_argb);
1727*4e366538SXin Li }
1728*4e366538SXin Li 
ShowJPegInfo(const uint8_t * sample,size_t sample_size)1729*4e366538SXin Li static int ShowJPegInfo(const uint8_t* sample, size_t sample_size) {
1730*4e366538SXin Li   MJpegDecoder mjpeg_decoder;
1731*4e366538SXin Li   LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size);
1732*4e366538SXin Li 
1733*4e366538SXin Li   int width = mjpeg_decoder.GetWidth();
1734*4e366538SXin Li   int height = mjpeg_decoder.GetHeight();
1735*4e366538SXin Li 
1736*4e366538SXin Li   // YUV420
1737*4e366538SXin Li   if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr &&
1738*4e366538SXin Li       mjpeg_decoder.GetNumComponents() == 3 &&
1739*4e366538SXin Li       mjpeg_decoder.GetVertSampFactor(0) == 2 &&
1740*4e366538SXin Li       mjpeg_decoder.GetHorizSampFactor(0) == 2 &&
1741*4e366538SXin Li       mjpeg_decoder.GetVertSampFactor(1) == 1 &&
1742*4e366538SXin Li       mjpeg_decoder.GetHorizSampFactor(1) == 1 &&
1743*4e366538SXin Li       mjpeg_decoder.GetVertSampFactor(2) == 1 &&
1744*4e366538SXin Li       mjpeg_decoder.GetHorizSampFactor(2) == 1) {
1745*4e366538SXin Li     printf("JPeg is J420, %dx%d %d bytes\n", width, height,
1746*4e366538SXin Li            static_cast<int>(sample_size));
1747*4e366538SXin Li     // YUV422
1748*4e366538SXin Li   } else if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr &&
1749*4e366538SXin Li              mjpeg_decoder.GetNumComponents() == 3 &&
1750*4e366538SXin Li              mjpeg_decoder.GetVertSampFactor(0) == 1 &&
1751*4e366538SXin Li              mjpeg_decoder.GetHorizSampFactor(0) == 2 &&
1752*4e366538SXin Li              mjpeg_decoder.GetVertSampFactor(1) == 1 &&
1753*4e366538SXin Li              mjpeg_decoder.GetHorizSampFactor(1) == 1 &&
1754*4e366538SXin Li              mjpeg_decoder.GetVertSampFactor(2) == 1 &&
1755*4e366538SXin Li              mjpeg_decoder.GetHorizSampFactor(2) == 1) {
1756*4e366538SXin Li     printf("JPeg is J422, %dx%d %d bytes\n", width, height,
1757*4e366538SXin Li            static_cast<int>(sample_size));
1758*4e366538SXin Li     // YUV444
1759*4e366538SXin Li   } else if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr &&
1760*4e366538SXin Li              mjpeg_decoder.GetNumComponents() == 3 &&
1761*4e366538SXin Li              mjpeg_decoder.GetVertSampFactor(0) == 1 &&
1762*4e366538SXin Li              mjpeg_decoder.GetHorizSampFactor(0) == 1 &&
1763*4e366538SXin Li              mjpeg_decoder.GetVertSampFactor(1) == 1 &&
1764*4e366538SXin Li              mjpeg_decoder.GetHorizSampFactor(1) == 1 &&
1765*4e366538SXin Li              mjpeg_decoder.GetVertSampFactor(2) == 1 &&
1766*4e366538SXin Li              mjpeg_decoder.GetHorizSampFactor(2) == 1) {
1767*4e366538SXin Li     printf("JPeg is J444, %dx%d %d bytes\n", width, height,
1768*4e366538SXin Li            static_cast<int>(sample_size));
1769*4e366538SXin Li     // YUV400
1770*4e366538SXin Li   } else if (mjpeg_decoder.GetColorSpace() ==
1771*4e366538SXin Li                  MJpegDecoder::kColorSpaceGrayscale &&
1772*4e366538SXin Li              mjpeg_decoder.GetNumComponents() == 1 &&
1773*4e366538SXin Li              mjpeg_decoder.GetVertSampFactor(0) == 1 &&
1774*4e366538SXin Li              mjpeg_decoder.GetHorizSampFactor(0) == 1) {
1775*4e366538SXin Li     printf("JPeg is J400, %dx%d %d bytes\n", width, height,
1776*4e366538SXin Li            static_cast<int>(sample_size));
1777*4e366538SXin Li   } else {
1778*4e366538SXin Li     // Unknown colorspace.
1779*4e366538SXin Li     printf("JPeg is Unknown colorspace.\n");
1780*4e366538SXin Li   }
1781*4e366538SXin Li   mjpeg_decoder.UnloadFrame();
1782*4e366538SXin Li   return ret;
1783*4e366538SXin Li }
1784*4e366538SXin Li 
TEST_F(LibYUVConvertTest,TestMJPGInfo)1785*4e366538SXin Li TEST_F(LibYUVConvertTest, TestMJPGInfo) {
1786*4e366538SXin Li   EXPECT_EQ(1, ShowJPegInfo(kTest0Jpg, kTest0JpgLen));
1787*4e366538SXin Li   EXPECT_EQ(1, ShowJPegInfo(kTest1Jpg, kTest1JpgLen));
1788*4e366538SXin Li   EXPECT_EQ(1, ShowJPegInfo(kTest2Jpg, kTest2JpgLen));
1789*4e366538SXin Li   EXPECT_EQ(1, ShowJPegInfo(kTest3Jpg, kTest3JpgLen));
1790*4e366538SXin Li   EXPECT_EQ(1, ShowJPegInfo(kTest4Jpg,
1791*4e366538SXin Li                             kTest4JpgLen));  // Valid but unsupported.
1792*4e366538SXin Li }
1793*4e366538SXin Li #endif  // HAVE_JPEG
1794*4e366538SXin Li 
TEST_F(LibYUVConvertTest,NV12Crop)1795*4e366538SXin Li TEST_F(LibYUVConvertTest, NV12Crop) {
1796*4e366538SXin Li   const int SUBSAMP_X = 2;
1797*4e366538SXin Li   const int SUBSAMP_Y = 2;
1798*4e366538SXin Li   const int kWidth = benchmark_width_;
1799*4e366538SXin Li   const int kHeight = benchmark_height_;
1800*4e366538SXin Li   const int crop_y =
1801*4e366538SXin Li       ((benchmark_height_ - (benchmark_height_ * 360 / 480)) / 2 + 1) & ~1;
1802*4e366538SXin Li   const int kDestWidth = benchmark_width_;
1803*4e366538SXin Li   const int kDestHeight = benchmark_height_ - crop_y * 2;
1804*4e366538SXin Li   const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X);
1805*4e366538SXin Li   const int sample_size =
1806*4e366538SXin Li       kWidth * kHeight + kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y) * 2;
1807*4e366538SXin Li   align_buffer_page_end(src_y, sample_size);
1808*4e366538SXin Li   uint8_t* src_uv = src_y + kWidth * kHeight;
1809*4e366538SXin Li 
1810*4e366538SXin Li   align_buffer_page_end(dst_y, kDestWidth * kDestHeight);
1811*4e366538SXin Li   align_buffer_page_end(dst_u, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1812*4e366538SXin Li                                    SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1813*4e366538SXin Li   align_buffer_page_end(dst_v, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1814*4e366538SXin Li                                    SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1815*4e366538SXin Li 
1816*4e366538SXin Li   align_buffer_page_end(dst_y_2, kDestWidth * kDestHeight);
1817*4e366538SXin Li   align_buffer_page_end(dst_u_2, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1818*4e366538SXin Li                                      SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1819*4e366538SXin Li   align_buffer_page_end(dst_v_2, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1820*4e366538SXin Li                                      SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1821*4e366538SXin Li 
1822*4e366538SXin Li   for (int i = 0; i < kHeight * kWidth; ++i) {
1823*4e366538SXin Li     src_y[i] = (fastrand() & 0xff);
1824*4e366538SXin Li   }
1825*4e366538SXin Li   for (int i = 0; i < (SUBSAMPLE(kHeight, SUBSAMP_Y) * kStrideUV) * 2; ++i) {
1826*4e366538SXin Li     src_uv[i] = (fastrand() & 0xff);
1827*4e366538SXin Li   }
1828*4e366538SXin Li   memset(dst_y, 1, kDestWidth * kDestHeight);
1829*4e366538SXin Li   memset(dst_u, 2,
1830*4e366538SXin Li          SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1831*4e366538SXin Li   memset(dst_v, 3,
1832*4e366538SXin Li          SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1833*4e366538SXin Li   memset(dst_y_2, 1, kDestWidth * kDestHeight);
1834*4e366538SXin Li   memset(dst_u_2, 2,
1835*4e366538SXin Li          SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1836*4e366538SXin Li   memset(dst_v_2, 3,
1837*4e366538SXin Li          SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1838*4e366538SXin Li 
1839*4e366538SXin Li   ConvertToI420(src_y, sample_size, dst_y_2, kDestWidth, dst_u_2,
1840*4e366538SXin Li                 SUBSAMPLE(kDestWidth, SUBSAMP_X), dst_v_2,
1841*4e366538SXin Li                 SUBSAMPLE(kDestWidth, SUBSAMP_X), 0, crop_y, kWidth, kHeight,
1842*4e366538SXin Li                 kDestWidth, kDestHeight, libyuv::kRotate0, libyuv::FOURCC_NV12);
1843*4e366538SXin Li 
1844*4e366538SXin Li   NV12ToI420(src_y + crop_y * kWidth, kWidth,
1845*4e366538SXin Li              src_uv + (crop_y / 2) * kStrideUV * 2, kStrideUV * 2, dst_y,
1846*4e366538SXin Li              kDestWidth, dst_u, SUBSAMPLE(kDestWidth, SUBSAMP_X), dst_v,
1847*4e366538SXin Li              SUBSAMPLE(kDestWidth, SUBSAMP_X), kDestWidth, kDestHeight);
1848*4e366538SXin Li 
1849*4e366538SXin Li   for (int i = 0; i < kDestHeight; ++i) {
1850*4e366538SXin Li     for (int j = 0; j < kDestWidth; ++j) {
1851*4e366538SXin Li       EXPECT_EQ(dst_y[i * kWidth + j], dst_y_2[i * kWidth + j]);
1852*4e366538SXin Li     }
1853*4e366538SXin Li   }
1854*4e366538SXin Li   for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
1855*4e366538SXin Li     for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
1856*4e366538SXin Li       EXPECT_EQ(dst_u[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j],
1857*4e366538SXin Li                 dst_u_2[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
1858*4e366538SXin Li     }
1859*4e366538SXin Li   }
1860*4e366538SXin Li   for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
1861*4e366538SXin Li     for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
1862*4e366538SXin Li       EXPECT_EQ(dst_v[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j],
1863*4e366538SXin Li                 dst_v_2[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
1864*4e366538SXin Li     }
1865*4e366538SXin Li   }
1866*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1867*4e366538SXin Li   free_aligned_buffer_page_end(dst_u);
1868*4e366538SXin Li   free_aligned_buffer_page_end(dst_v);
1869*4e366538SXin Li   free_aligned_buffer_page_end(dst_y_2);
1870*4e366538SXin Li   free_aligned_buffer_page_end(dst_u_2);
1871*4e366538SXin Li   free_aligned_buffer_page_end(dst_v_2);
1872*4e366538SXin Li   free_aligned_buffer_page_end(src_y);
1873*4e366538SXin Li }
1874*4e366538SXin Li 
TEST_F(LibYUVConvertTest,I420CropOddY)1875*4e366538SXin Li TEST_F(LibYUVConvertTest, I420CropOddY) {
1876*4e366538SXin Li   const int SUBSAMP_X = 2;
1877*4e366538SXin Li   const int SUBSAMP_Y = 2;
1878*4e366538SXin Li   const int kWidth = benchmark_width_;
1879*4e366538SXin Li   const int kHeight = benchmark_height_;
1880*4e366538SXin Li   const int crop_y = benchmark_height_ > 1 ? 1 : 0;
1881*4e366538SXin Li   const int kDestWidth = benchmark_width_;
1882*4e366538SXin Li   const int kDestHeight = benchmark_height_ - crop_y * 2;
1883*4e366538SXin Li   const int kStrideU = SUBSAMPLE(kWidth, SUBSAMP_X);
1884*4e366538SXin Li   const int kStrideV = SUBSAMPLE(kWidth, SUBSAMP_X);
1885*4e366538SXin Li   const int sample_size = kWidth * kHeight +
1886*4e366538SXin Li                           kStrideU * SUBSAMPLE(kHeight, SUBSAMP_Y) +
1887*4e366538SXin Li                           kStrideV * SUBSAMPLE(kHeight, SUBSAMP_Y);
1888*4e366538SXin Li   align_buffer_page_end(src_y, sample_size);
1889*4e366538SXin Li   uint8_t* src_u = src_y + kWidth * kHeight;
1890*4e366538SXin Li   uint8_t* src_v = src_u + kStrideU * SUBSAMPLE(kHeight, SUBSAMP_Y);
1891*4e366538SXin Li 
1892*4e366538SXin Li   align_buffer_page_end(dst_y, kDestWidth * kDestHeight);
1893*4e366538SXin Li   align_buffer_page_end(dst_u, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1894*4e366538SXin Li                                    SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1895*4e366538SXin Li   align_buffer_page_end(dst_v, SUBSAMPLE(kDestWidth, SUBSAMP_X) *
1896*4e366538SXin Li                                    SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1897*4e366538SXin Li 
1898*4e366538SXin Li   for (int i = 0; i < kHeight * kWidth; ++i) {
1899*4e366538SXin Li     src_y[i] = (fastrand() & 0xff);
1900*4e366538SXin Li   }
1901*4e366538SXin Li   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * kStrideU; ++i) {
1902*4e366538SXin Li     src_u[i] = (fastrand() & 0xff);
1903*4e366538SXin Li   }
1904*4e366538SXin Li   for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y) * kStrideV; ++i) {
1905*4e366538SXin Li     src_v[i] = (fastrand() & 0xff);
1906*4e366538SXin Li   }
1907*4e366538SXin Li   memset(dst_y, 1, kDestWidth * kDestHeight);
1908*4e366538SXin Li   memset(dst_u, 2,
1909*4e366538SXin Li          SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1910*4e366538SXin Li   memset(dst_v, 3,
1911*4e366538SXin Li          SUBSAMPLE(kDestWidth, SUBSAMP_X) * SUBSAMPLE(kDestHeight, SUBSAMP_Y));
1912*4e366538SXin Li 
1913*4e366538SXin Li   MaskCpuFlags(benchmark_cpu_info_);
1914*4e366538SXin Li   for (int i = 0; i < benchmark_iterations_; ++i) {
1915*4e366538SXin Li     ConvertToI420(src_y, sample_size, dst_y, kDestWidth, dst_u,
1916*4e366538SXin Li                   SUBSAMPLE(kDestWidth, SUBSAMP_X), dst_v,
1917*4e366538SXin Li                   SUBSAMPLE(kDestWidth, SUBSAMP_X), 0, crop_y, kWidth, kHeight,
1918*4e366538SXin Li                   kDestWidth, kDestHeight, libyuv::kRotate0,
1919*4e366538SXin Li                   libyuv::FOURCC_I420);
1920*4e366538SXin Li   }
1921*4e366538SXin Li 
1922*4e366538SXin Li   for (int i = 0; i < kDestHeight; ++i) {
1923*4e366538SXin Li     for (int j = 0; j < kDestWidth; ++j) {
1924*4e366538SXin Li       EXPECT_EQ(src_y[crop_y * kWidth + i * kWidth + j],
1925*4e366538SXin Li                 dst_y[i * kDestWidth + j]);
1926*4e366538SXin Li     }
1927*4e366538SXin Li   }
1928*4e366538SXin Li   for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
1929*4e366538SXin Li     for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
1930*4e366538SXin Li       EXPECT_EQ(src_u[(crop_y / 2 + i) * kStrideU + j],
1931*4e366538SXin Li                 dst_u[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
1932*4e366538SXin Li     }
1933*4e366538SXin Li   }
1934*4e366538SXin Li   for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) {
1935*4e366538SXin Li     for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) {
1936*4e366538SXin Li       EXPECT_EQ(src_v[(crop_y / 2 + i) * kStrideV + j],
1937*4e366538SXin Li                 dst_v[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]);
1938*4e366538SXin Li     }
1939*4e366538SXin Li   }
1940*4e366538SXin Li 
1941*4e366538SXin Li   free_aligned_buffer_page_end(dst_y);
1942*4e366538SXin Li   free_aligned_buffer_page_end(dst_u);
1943*4e366538SXin Li   free_aligned_buffer_page_end(dst_v);
1944*4e366538SXin Li   free_aligned_buffer_page_end(src_y);
1945*4e366538SXin Li }
1946*4e366538SXin Li 
1947*4e366538SXin Li #define TESTPTOB(NAME, UYVYTOI420, UYVYTONV12)                                \
1948*4e366538SXin Li   TEST_F(LibYUVConvertTest, NAME) {                                           \
1949*4e366538SXin Li     const int kWidth = benchmark_width_;                                      \
1950*4e366538SXin Li     const int kHeight = benchmark_height_;                                    \
1951*4e366538SXin Li                                                                               \
1952*4e366538SXin Li     align_buffer_page_end(orig_uyvy, 4 * SUBSAMPLE(kWidth, 2) * kHeight);     \
1953*4e366538SXin Li     align_buffer_page_end(orig_y, kWidth* kHeight);                           \
1954*4e366538SXin Li     align_buffer_page_end(orig_u,                                             \
1955*4e366538SXin Li                           SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));      \
1956*4e366538SXin Li     align_buffer_page_end(orig_v,                                             \
1957*4e366538SXin Li                           SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));      \
1958*4e366538SXin Li                                                                               \
1959*4e366538SXin Li     align_buffer_page_end(dst_y_orig, kWidth* kHeight);                       \
1960*4e366538SXin Li     align_buffer_page_end(dst_uv_orig,                                        \
1961*4e366538SXin Li                           2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));  \
1962*4e366538SXin Li                                                                               \
1963*4e366538SXin Li     align_buffer_page_end(dst_y, kWidth* kHeight);                            \
1964*4e366538SXin Li     align_buffer_page_end(dst_uv,                                             \
1965*4e366538SXin Li                           2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));  \
1966*4e366538SXin Li                                                                               \
1967*4e366538SXin Li     MemRandomize(orig_uyvy, 4 * SUBSAMPLE(kWidth, 2) * kHeight);              \
1968*4e366538SXin Li                                                                               \
1969*4e366538SXin Li     /* Convert UYVY to NV12 in 2 steps for reference */                       \
1970*4e366538SXin Li     libyuv::UYVYTOI420(orig_uyvy, 4 * SUBSAMPLE(kWidth, 2), orig_y, kWidth,   \
1971*4e366538SXin Li                        orig_u, SUBSAMPLE(kWidth, 2), orig_v,                  \
1972*4e366538SXin Li                        SUBSAMPLE(kWidth, 2), kWidth, kHeight);                \
1973*4e366538SXin Li     libyuv::I420ToNV12(orig_y, kWidth, orig_u, SUBSAMPLE(kWidth, 2), orig_v,  \
1974*4e366538SXin Li                        SUBSAMPLE(kWidth, 2), dst_y_orig, kWidth, dst_uv_orig, \
1975*4e366538SXin Li                        2 * SUBSAMPLE(kWidth, 2), kWidth, kHeight);            \
1976*4e366538SXin Li                                                                               \
1977*4e366538SXin Li     /* Convert to NV12 */                                                     \
1978*4e366538SXin Li     for (int i = 0; i < benchmark_iterations_; ++i) {                         \
1979*4e366538SXin Li       libyuv::UYVYTONV12(orig_uyvy, 4 * SUBSAMPLE(kWidth, 2), dst_y, kWidth,  \
1980*4e366538SXin Li                          dst_uv, 2 * SUBSAMPLE(kWidth, 2), kWidth, kHeight);  \
1981*4e366538SXin Li     }                                                                         \
1982*4e366538SXin Li                                                                               \
1983*4e366538SXin Li     for (int i = 0; i < kWidth * kHeight; ++i) {                              \
1984*4e366538SXin Li       EXPECT_EQ(orig_y[i], dst_y[i]);                                         \
1985*4e366538SXin Li     }                                                                         \
1986*4e366538SXin Li     for (int i = 0; i < kWidth * kHeight; ++i) {                              \
1987*4e366538SXin Li       EXPECT_EQ(dst_y_orig[i], dst_y[i]);                                     \
1988*4e366538SXin Li     }                                                                         \
1989*4e366538SXin Li     for (int i = 0; i < 2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2);     \
1990*4e366538SXin Li          ++i) {                                                               \
1991*4e366538SXin Li       EXPECT_EQ(dst_uv_orig[i], dst_uv[i]);                                   \
1992*4e366538SXin Li     }                                                                         \
1993*4e366538SXin Li                                                                               \
1994*4e366538SXin Li     free_aligned_buffer_page_end(orig_uyvy);                                  \
1995*4e366538SXin Li     free_aligned_buffer_page_end(orig_y);                                     \
1996*4e366538SXin Li     free_aligned_buffer_page_end(orig_u);                                     \
1997*4e366538SXin Li     free_aligned_buffer_page_end(orig_v);                                     \
1998*4e366538SXin Li     free_aligned_buffer_page_end(dst_y_orig);                                 \
1999*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv_orig);                                \
2000*4e366538SXin Li     free_aligned_buffer_page_end(dst_y);                                      \
2001*4e366538SXin Li     free_aligned_buffer_page_end(dst_uv);                                     \
2002*4e366538SXin Li   }
2003*4e366538SXin Li 
TESTPTOB(TestYUY2ToNV12,YUY2ToI420,YUY2ToNV12)2004*4e366538SXin Li TESTPTOB(TestYUY2ToNV12, YUY2ToI420, YUY2ToNV12)
2005*4e366538SXin Li TESTPTOB(TestUYVYToNV12, UYVYToI420, UYVYToNV12)
2006*4e366538SXin Li 
2007*4e366538SXin Li TEST_F(LibYUVConvertTest, MM21ToYUY2) {
2008*4e366538SXin Li   const int kWidth = (benchmark_width_ + 15) & (~15);
2009*4e366538SXin Li   const int kHeight = (benchmark_height_ + 31) & (~31);
2010*4e366538SXin Li 
2011*4e366538SXin Li   align_buffer_page_end(orig_y, kWidth * kHeight);
2012*4e366538SXin Li   align_buffer_page_end(orig_uv,
2013*4e366538SXin Li                         2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));
2014*4e366538SXin Li 
2015*4e366538SXin Li   align_buffer_page_end(tmp_y, kWidth * kHeight);
2016*4e366538SXin Li   align_buffer_page_end(tmp_u, SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));
2017*4e366538SXin Li   align_buffer_page_end(tmp_v, SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));
2018*4e366538SXin Li 
2019*4e366538SXin Li   align_buffer_page_end(dst_yuyv, 4 * SUBSAMPLE(kWidth, 2) * kHeight);
2020*4e366538SXin Li   align_buffer_page_end(golden_yuyv, 4 * SUBSAMPLE(kWidth, 2) * kHeight);
2021*4e366538SXin Li 
2022*4e366538SXin Li   MemRandomize(orig_y, kWidth * kHeight);
2023*4e366538SXin Li   MemRandomize(orig_uv, 2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2));
2024*4e366538SXin Li 
2025*4e366538SXin Li   /* Convert MM21 to YUY2 in 2 steps for reference */
2026*4e366538SXin Li   libyuv::MM21ToI420(orig_y, kWidth, orig_uv, 2 * SUBSAMPLE(kWidth, 2), tmp_y,
2027*4e366538SXin Li                      kWidth, tmp_u, SUBSAMPLE(kWidth, 2), tmp_v,
2028*4e366538SXin Li                      SUBSAMPLE(kWidth, 2), kWidth, kHeight);
2029*4e366538SXin Li   libyuv::I420ToYUY2(tmp_y, kWidth, tmp_u, SUBSAMPLE(kWidth, 2), tmp_v,
2030*4e366538SXin Li                      SUBSAMPLE(kWidth, 2), golden_yuyv,
2031*4e366538SXin Li                      4 * SUBSAMPLE(kWidth, 2), kWidth, kHeight);
2032*4e366538SXin Li 
2033*4e366538SXin Li   /* Convert to NV12 */
2034*4e366538SXin Li   for (int i = 0; i < benchmark_iterations_; ++i) {
2035*4e366538SXin Li     libyuv::MM21ToYUY2(orig_y, kWidth, orig_uv, 2 * SUBSAMPLE(kWidth, 2),
2036*4e366538SXin Li                        dst_yuyv, 4 * SUBSAMPLE(kWidth, 2), kWidth, kHeight);
2037*4e366538SXin Li   }
2038*4e366538SXin Li 
2039*4e366538SXin Li   for (int i = 0; i < 4 * SUBSAMPLE(kWidth, 2) * kHeight; ++i) {
2040*4e366538SXin Li     EXPECT_EQ(dst_yuyv[i], golden_yuyv[i]);
2041*4e366538SXin Li   }
2042*4e366538SXin Li 
2043*4e366538SXin Li   free_aligned_buffer_page_end(orig_y);
2044*4e366538SXin Li   free_aligned_buffer_page_end(orig_uv);
2045*4e366538SXin Li   free_aligned_buffer_page_end(tmp_y);
2046*4e366538SXin Li   free_aligned_buffer_page_end(tmp_u);
2047*4e366538SXin Li   free_aligned_buffer_page_end(tmp_v);
2048*4e366538SXin Li   free_aligned_buffer_page_end(dst_yuyv);
2049*4e366538SXin Li   free_aligned_buffer_page_end(golden_yuyv);
2050*4e366538SXin Li }
2051*4e366538SXin Li 
2052*4e366538SXin Li // Test RGB24 to J420 is exact
2053*4e366538SXin Li #if defined(LIBYUV_BIT_EXACT)
TEST_F(LibYUVConvertTest,TestRGB24ToJ420)2054*4e366538SXin Li TEST_F(LibYUVConvertTest, TestRGB24ToJ420) {
2055*4e366538SXin Li   const int kSize = 256;
2056*4e366538SXin Li   align_buffer_page_end(orig_rgb24, kSize * 3 * 2);  // 2 rows of RGB24
2057*4e366538SXin Li   align_buffer_page_end(dest_j420, kSize * 3 / 2 * 2);
2058*4e366538SXin Li   int iterations256 = (benchmark_width_ * benchmark_height_ + (kSize * 2 - 1)) /
2059*4e366538SXin Li                       (kSize * 2) * benchmark_iterations_;
2060*4e366538SXin Li 
2061*4e366538SXin Li   for (int i = 0; i < kSize * 3 * 2; ++i) {
2062*4e366538SXin Li     orig_rgb24[i] = i;
2063*4e366538SXin Li   }
2064*4e366538SXin Li 
2065*4e366538SXin Li   for (int i = 0; i < iterations256; ++i) {
2066*4e366538SXin Li     RGB24ToJ420(orig_rgb24, kSize * 3, dest_j420, kSize,  // Y plane
2067*4e366538SXin Li                 dest_j420 + kSize * 2, kSize / 2,         // U plane
2068*4e366538SXin Li                 dest_j420 + kSize * 5 / 2, kSize / 2,     // V plane
2069*4e366538SXin Li                 kSize, 2);
2070*4e366538SXin Li   }
2071*4e366538SXin Li 
2072*4e366538SXin Li   uint32_t checksum = HashDjb2(dest_j420, kSize * 3 / 2 * 2, 5381);
2073*4e366538SXin Li   EXPECT_EQ(2755440272u, checksum);
2074*4e366538SXin Li 
2075*4e366538SXin Li   free_aligned_buffer_page_end(orig_rgb24);
2076*4e366538SXin Li   free_aligned_buffer_page_end(dest_j420);
2077*4e366538SXin Li }
2078*4e366538SXin Li #endif
2079*4e366538SXin Li 
2080*4e366538SXin Li // Test RGB24 to I420 is exact
2081*4e366538SXin Li #if defined(LIBYUV_BIT_EXACT)
TEST_F(LibYUVConvertTest,TestRGB24ToI420)2082*4e366538SXin Li TEST_F(LibYUVConvertTest, TestRGB24ToI420) {
2083*4e366538SXin Li   const int kSize = 256;
2084*4e366538SXin Li   align_buffer_page_end(orig_rgb24, kSize * 3 * 2);  // 2 rows of RGB24
2085*4e366538SXin Li   align_buffer_page_end(dest_i420, kSize * 3 / 2 * 2);
2086*4e366538SXin Li   int iterations256 = (benchmark_width_ * benchmark_height_ + (kSize * 2 - 1)) /
2087*4e366538SXin Li                       (kSize * 2) * benchmark_iterations_;
2088*4e366538SXin Li 
2089*4e366538SXin Li   for (int i = 0; i < kSize * 3 * 2; ++i) {
2090*4e366538SXin Li     orig_rgb24[i] = i;
2091*4e366538SXin Li   }
2092*4e366538SXin Li 
2093*4e366538SXin Li   for (int i = 0; i < iterations256; ++i) {
2094*4e366538SXin Li     RGB24ToI420(orig_rgb24, kSize * 3, dest_i420, kSize,  // Y plane
2095*4e366538SXin Li                 dest_i420 + kSize * 2, kSize / 2,         // U plane
2096*4e366538SXin Li                 dest_i420 + kSize * 5 / 2, kSize / 2,     // V plane
2097*4e366538SXin Li                 kSize, 2);
2098*4e366538SXin Li   }
2099*4e366538SXin Li 
2100*4e366538SXin Li   uint32_t checksum = HashDjb2(dest_i420, kSize * 3 / 2 * 2, 5381);
2101*4e366538SXin Li   EXPECT_EQ(1526656597u, checksum);
2102*4e366538SXin Li 
2103*4e366538SXin Li   free_aligned_buffer_page_end(orig_rgb24);
2104*4e366538SXin Li   free_aligned_buffer_page_end(dest_i420);
2105*4e366538SXin Li }
2106*4e366538SXin Li #endif
2107*4e366538SXin Li 
2108*4e366538SXin Li #endif  // !defined(LEAN_TESTS)
2109*4e366538SXin Li 
2110*4e366538SXin Li }  // namespace libyuv
2111