1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libyuv/unit_test/convert_test.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1033 @@ 1.4 +/* 1.5 + * Copyright 2011 The LibYuv Project Authors. All rights reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 +#include <stdlib.h> 1.15 +#include <time.h> 1.16 + 1.17 +#include "libyuv/compare.h" 1.18 +#include "libyuv/convert.h" 1.19 +#include "libyuv/convert_argb.h" 1.20 +#include "libyuv/convert_from.h" 1.21 +#include "libyuv/convert_from_argb.h" 1.22 +#include "libyuv/cpu_id.h" 1.23 +#include "libyuv/format_conversion.h" 1.24 +#ifdef HAVE_JPEG 1.25 +#include "libyuv/mjpeg_decoder.h" 1.26 +#endif 1.27 +#include "libyuv/planar_functions.h" 1.28 +#include "libyuv/rotate.h" 1.29 +#include "libyuv/row.h" 1.30 +#include "../unit_test/unit_test.h" 1.31 + 1.32 +#if defined(_MSC_VER) 1.33 +#define SIMD_ALIGNED(var) __declspec(align(16)) var 1.34 +#else // __GNUC__ 1.35 +#define SIMD_ALIGNED(var) var __attribute__((aligned(16))) 1.36 +#endif 1.37 + 1.38 +namespace libyuv { 1.39 + 1.40 +#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) 1.41 + 1.42 +#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.43 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ 1.44 +TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ 1.45 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.46 + const int kHeight = benchmark_height_; \ 1.47 + align_buffer_64(src_y, kWidth * kHeight + OFF); \ 1.48 + align_buffer_64(src_u, \ 1.49 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 1.50 + SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 1.51 + align_buffer_64(src_v, \ 1.52 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 1.53 + SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 1.54 + align_buffer_64(dst_y_c, kWidth * kHeight); \ 1.55 + align_buffer_64(dst_u_c, \ 1.56 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.57 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.58 + align_buffer_64(dst_v_c, \ 1.59 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.60 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.61 + align_buffer_64(dst_y_opt, kWidth * kHeight); \ 1.62 + align_buffer_64(dst_u_opt, \ 1.63 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.64 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.65 + align_buffer_64(dst_v_opt, \ 1.66 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.67 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.68 + srandom(time(NULL)); \ 1.69 + for (int i = 0; i < kHeight; ++i) \ 1.70 + for (int j = 0; j < kWidth; ++j) \ 1.71 + src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \ 1.72 + for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \ 1.73 + for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \ 1.74 + src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 1.75 + (random() & 0xff); \ 1.76 + src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 1.77 + (random() & 0xff); \ 1.78 + } \ 1.79 + } \ 1.80 + memset(dst_y_c, 1, kWidth * kHeight); \ 1.81 + memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.82 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.83 + memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.84 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.85 + memset(dst_y_opt, 101, kWidth * kHeight); \ 1.86 + memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.87 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.88 + memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.89 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.90 + MaskCpuFlags(0); \ 1.91 + SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 1.92 + src_u + OFF, \ 1.93 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.94 + src_v + OFF, \ 1.95 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.96 + dst_y_c, kWidth, \ 1.97 + dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.98 + dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.99 + kWidth, NEG kHeight); \ 1.100 + MaskCpuFlags(-1); \ 1.101 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.102 + SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 1.103 + src_u + OFF, \ 1.104 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.105 + src_v + OFF, \ 1.106 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.107 + dst_y_opt, kWidth, \ 1.108 + dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.109 + dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.110 + kWidth, NEG kHeight); \ 1.111 + } \ 1.112 + int max_diff = 0; \ 1.113 + for (int i = 0; i < kHeight; ++i) { \ 1.114 + for (int j = 0; j < kWidth; ++j) { \ 1.115 + int abs_diff = \ 1.116 + abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 1.117 + static_cast<int>(dst_y_opt[i * kWidth + j])); \ 1.118 + if (abs_diff > max_diff) { \ 1.119 + max_diff = abs_diff; \ 1.120 + } \ 1.121 + } \ 1.122 + } \ 1.123 + EXPECT_LE(max_diff, 0); \ 1.124 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.125 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 1.126 + int abs_diff = \ 1.127 + abs(static_cast<int>(dst_u_c[i * \ 1.128 + SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 1.129 + static_cast<int>(dst_u_opt[i * \ 1.130 + SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 1.131 + if (abs_diff > max_diff) { \ 1.132 + max_diff = abs_diff; \ 1.133 + } \ 1.134 + } \ 1.135 + } \ 1.136 + EXPECT_LE(max_diff, 3); \ 1.137 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.138 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 1.139 + int abs_diff = \ 1.140 + abs(static_cast<int>(dst_v_c[i * \ 1.141 + SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 1.142 + static_cast<int>(dst_v_opt[i * \ 1.143 + SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 1.144 + if (abs_diff > max_diff) { \ 1.145 + max_diff = abs_diff; \ 1.146 + } \ 1.147 + } \ 1.148 + } \ 1.149 + EXPECT_LE(max_diff, 3); \ 1.150 + free_aligned_buffer_64(dst_y_c); \ 1.151 + free_aligned_buffer_64(dst_u_c); \ 1.152 + free_aligned_buffer_64(dst_v_c); \ 1.153 + free_aligned_buffer_64(dst_y_opt); \ 1.154 + free_aligned_buffer_64(dst_u_opt); \ 1.155 + free_aligned_buffer_64(dst_v_opt); \ 1.156 + free_aligned_buffer_64(src_y); \ 1.157 + free_aligned_buffer_64(src_u); \ 1.158 + free_aligned_buffer_64(src_v); \ 1.159 +} 1.160 + 1.161 +#define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.162 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 1.163 + TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.164 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.165 + benchmark_width_ - 4, _Any, +, 0) \ 1.166 + TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.167 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.168 + benchmark_width_, _Unaligned, +, 1) \ 1.169 + TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.170 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.171 + benchmark_width_, _Invert, -, 0) \ 1.172 + TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.173 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.174 + benchmark_width_, _Opt, +, 0) 1.175 + 1.176 +TESTPLANARTOP(I420, 2, 2, I420, 2, 2) 1.177 +TESTPLANARTOP(I422, 2, 1, I420, 2, 2) 1.178 +TESTPLANARTOP(I444, 1, 1, I420, 2, 2) 1.179 +TESTPLANARTOP(I411, 4, 1, I420, 2, 2) 1.180 +TESTPLANARTOP(I420, 2, 2, I422, 2, 1) 1.181 +TESTPLANARTOP(I420, 2, 2, I444, 1, 1) 1.182 +TESTPLANARTOP(I420, 2, 2, I411, 4, 1) 1.183 +TESTPLANARTOP(I420, 2, 2, I420Mirror, 2, 2) 1.184 +TESTPLANARTOP(I422, 2, 1, I422, 2, 1) 1.185 +TESTPLANARTOP(I444, 1, 1, I444, 1, 1) 1.186 + 1.187 +#define TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.188 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ 1.189 +TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ 1.190 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.191 + const int kHeight = benchmark_height_; \ 1.192 + align_buffer_64(src_y, kWidth * kHeight + OFF); \ 1.193 + align_buffer_64(src_u, \ 1.194 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 1.195 + SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 1.196 + align_buffer_64(src_v, \ 1.197 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 1.198 + SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 1.199 + align_buffer_64(dst_y_c, kWidth * kHeight); \ 1.200 + align_buffer_64(dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 1.201 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.202 + align_buffer_64(dst_y_opt, kWidth * kHeight); \ 1.203 + align_buffer_64(dst_uv_opt, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 1.204 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.205 + srandom(time(NULL)); \ 1.206 + for (int i = 0; i < kHeight; ++i) \ 1.207 + for (int j = 0; j < kWidth; ++j) \ 1.208 + src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \ 1.209 + for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \ 1.210 + for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \ 1.211 + src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 1.212 + (random() & 0xff); \ 1.213 + src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 1.214 + (random() & 0xff); \ 1.215 + } \ 1.216 + } \ 1.217 + memset(dst_y_c, 1, kWidth * kHeight); \ 1.218 + memset(dst_uv_c, 2, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 1.219 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.220 + memset(dst_y_opt, 101, kWidth * kHeight); \ 1.221 + memset(dst_uv_opt, 102, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 1.222 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.223 + MaskCpuFlags(0); \ 1.224 + SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 1.225 + src_u + OFF, \ 1.226 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.227 + src_v + OFF, \ 1.228 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.229 + dst_y_c, kWidth, \ 1.230 + dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X), \ 1.231 + kWidth, NEG kHeight); \ 1.232 + MaskCpuFlags(-1); \ 1.233 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.234 + SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 1.235 + src_u + OFF, \ 1.236 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.237 + src_v + OFF, \ 1.238 + SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.239 + dst_y_opt, kWidth, \ 1.240 + dst_uv_opt, \ 1.241 + SUBSAMPLE(kWidth * 2, SUBSAMP_X), \ 1.242 + kWidth, NEG kHeight); \ 1.243 + } \ 1.244 + int max_diff = 0; \ 1.245 + for (int i = 0; i < kHeight; ++i) { \ 1.246 + for (int j = 0; j < kWidth; ++j) { \ 1.247 + int abs_diff = \ 1.248 + abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 1.249 + static_cast<int>(dst_y_opt[i * kWidth + j])); \ 1.250 + if (abs_diff > max_diff) { \ 1.251 + max_diff = abs_diff; \ 1.252 + } \ 1.253 + } \ 1.254 + } \ 1.255 + EXPECT_LE(max_diff, 1); \ 1.256 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.257 + for (int j = 0; j < SUBSAMPLE(kWidth * 2, SUBSAMP_X); ++j) { \ 1.258 + int abs_diff = \ 1.259 + abs(static_cast<int>(dst_uv_c[i * \ 1.260 + SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j]) - \ 1.261 + static_cast<int>(dst_uv_opt[i * \ 1.262 + SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j])); \ 1.263 + if (abs_diff > max_diff) { \ 1.264 + max_diff = abs_diff; \ 1.265 + } \ 1.266 + } \ 1.267 + } \ 1.268 + EXPECT_LE(max_diff, 1); \ 1.269 + free_aligned_buffer_64(dst_y_c); \ 1.270 + free_aligned_buffer_64(dst_uv_c); \ 1.271 + free_aligned_buffer_64(dst_y_opt); \ 1.272 + free_aligned_buffer_64(dst_uv_opt); \ 1.273 + free_aligned_buffer_64(src_y); \ 1.274 + free_aligned_buffer_64(src_u); \ 1.275 + free_aligned_buffer_64(src_v); \ 1.276 +} 1.277 + 1.278 +#define TESTPLANARTOBP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.279 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 1.280 + TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.281 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.282 + benchmark_width_ - 4, _Any, +, 0) \ 1.283 + TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.284 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.285 + benchmark_width_, _Unaligned, +, 1) \ 1.286 + TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.287 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.288 + benchmark_width_, _Invert, -, 0) \ 1.289 + TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.290 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.291 + benchmark_width_, _Opt, +, 0) 1.292 + 1.293 +TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2) 1.294 +TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2) 1.295 + 1.296 +#define TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.297 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ 1.298 +TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ 1.299 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.300 + const int kHeight = benchmark_height_; \ 1.301 + align_buffer_64(src_y, kWidth * kHeight + OFF); \ 1.302 + align_buffer_64(src_uv, 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 1.303 + SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 1.304 + align_buffer_64(dst_y_c, kWidth * kHeight); \ 1.305 + align_buffer_64(dst_u_c, \ 1.306 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.307 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.308 + align_buffer_64(dst_v_c, \ 1.309 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.310 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.311 + align_buffer_64(dst_y_opt, kWidth * kHeight); \ 1.312 + align_buffer_64(dst_u_opt, \ 1.313 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.314 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.315 + align_buffer_64(dst_v_opt, \ 1.316 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.317 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.318 + srandom(time(NULL)); \ 1.319 + for (int i = 0; i < kHeight; ++i) \ 1.320 + for (int j = 0; j < kWidth; ++j) \ 1.321 + src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \ 1.322 + for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \ 1.323 + for (int j = 0; j < 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \ 1.324 + src_uv[(i * 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 1.325 + (random() & 0xff); \ 1.326 + } \ 1.327 + } \ 1.328 + memset(dst_y_c, 1, kWidth * kHeight); \ 1.329 + memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.330 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.331 + memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.332 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.333 + memset(dst_y_opt, 101, kWidth * kHeight); \ 1.334 + memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.335 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.336 + memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.337 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.338 + MaskCpuFlags(0); \ 1.339 + SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 1.340 + src_uv + OFF, \ 1.341 + 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.342 + dst_y_c, kWidth, \ 1.343 + dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.344 + dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.345 + kWidth, NEG kHeight); \ 1.346 + MaskCpuFlags(-1); \ 1.347 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.348 + SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 1.349 + src_uv + OFF, \ 1.350 + 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 1.351 + dst_y_opt, kWidth, \ 1.352 + dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.353 + dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.354 + kWidth, NEG kHeight); \ 1.355 + } \ 1.356 + int max_diff = 0; \ 1.357 + for (int i = 0; i < kHeight; ++i) { \ 1.358 + for (int j = 0; j < kWidth; ++j) { \ 1.359 + int abs_diff = \ 1.360 + abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 1.361 + static_cast<int>(dst_y_opt[i * kWidth + j])); \ 1.362 + if (abs_diff > max_diff) { \ 1.363 + max_diff = abs_diff; \ 1.364 + } \ 1.365 + } \ 1.366 + } \ 1.367 + EXPECT_LE(max_diff, 1); \ 1.368 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.369 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 1.370 + int abs_diff = \ 1.371 + abs(static_cast<int>(dst_u_c[i * \ 1.372 + SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 1.373 + static_cast<int>(dst_u_opt[i * \ 1.374 + SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 1.375 + if (abs_diff > max_diff) { \ 1.376 + max_diff = abs_diff; \ 1.377 + } \ 1.378 + } \ 1.379 + } \ 1.380 + EXPECT_LE(max_diff, 1); \ 1.381 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.382 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 1.383 + int abs_diff = \ 1.384 + abs(static_cast<int>(dst_v_c[i * \ 1.385 + SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 1.386 + static_cast<int>(dst_v_opt[i * \ 1.387 + SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 1.388 + if (abs_diff > max_diff) { \ 1.389 + max_diff = abs_diff; \ 1.390 + } \ 1.391 + } \ 1.392 + } \ 1.393 + EXPECT_LE(max_diff, 1); \ 1.394 + free_aligned_buffer_64(dst_y_c); \ 1.395 + free_aligned_buffer_64(dst_u_c); \ 1.396 + free_aligned_buffer_64(dst_v_c); \ 1.397 + free_aligned_buffer_64(dst_y_opt); \ 1.398 + free_aligned_buffer_64(dst_u_opt); \ 1.399 + free_aligned_buffer_64(dst_v_opt); \ 1.400 + free_aligned_buffer_64(src_y); \ 1.401 + free_aligned_buffer_64(src_uv); \ 1.402 +} 1.403 + 1.404 +#define TESTBIPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.405 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 1.406 + TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.407 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.408 + benchmark_width_ - 4, _Any, +, 0) \ 1.409 + TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.410 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.411 + benchmark_width_, _Unaligned, +, 1) \ 1.412 + TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.413 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.414 + benchmark_width_, _Invert, -, 0) \ 1.415 + TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 1.416 + FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.417 + benchmark_width_, _Opt, +, 0) 1.418 + 1.419 +TESTBIPLANARTOP(NV12, 2, 2, I420, 2, 2) 1.420 +TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2) 1.421 + 1.422 +#define ALIGNINT(V, ALIGN) (((V) + (ALIGN) - 1) / (ALIGN) * (ALIGN)) 1.423 + 1.424 +#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1.425 + YALIGN, W1280, DIFF, N, NEG, OFF, FMT_C, BPP_C) \ 1.426 +TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \ 1.427 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.428 + const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ 1.429 + const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \ 1.430 + const int kSizeUV = \ 1.431 + SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y); \ 1.432 + align_buffer_64(src_y, kWidth * kHeight + OFF); \ 1.433 + align_buffer_64(src_u, kSizeUV + OFF); \ 1.434 + align_buffer_64(src_v, kSizeUV + OFF); \ 1.435 + align_buffer_64(dst_argb_c, kStrideB * kHeight); \ 1.436 + align_buffer_64(dst_argb_opt, kStrideB * kHeight); \ 1.437 + srandom(time(NULL)); \ 1.438 + for (int i = 0; i < kWidth * kHeight; ++i) { \ 1.439 + src_y[i + OFF] = (random() & 0xff); \ 1.440 + } \ 1.441 + for (int i = 0; i < kSizeUV; ++i) { \ 1.442 + src_u[i + OFF] = (random() & 0xff); \ 1.443 + src_v[i + OFF] = (random() & 0xff); \ 1.444 + } \ 1.445 + memset(dst_argb_c, 1, kStrideB * kHeight); \ 1.446 + memset(dst_argb_opt, 101, kStrideB * kHeight); \ 1.447 + MaskCpuFlags(0); \ 1.448 + FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 1.449 + src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.450 + src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.451 + dst_argb_c, kStrideB, \ 1.452 + kWidth, NEG kHeight); \ 1.453 + MaskCpuFlags(-1); \ 1.454 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.455 + FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 1.456 + src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.457 + src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.458 + dst_argb_opt, kStrideB, \ 1.459 + kWidth, NEG kHeight); \ 1.460 + } \ 1.461 + int max_diff = 0; \ 1.462 + /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \ 1.463 + align_buffer_64(dst_argb32_c, kWidth * BPP_C * kHeight); \ 1.464 + align_buffer_64(dst_argb32_opt, kWidth * BPP_C * kHeight); \ 1.465 + memset(dst_argb32_c, 2, kWidth * BPP_C * kHeight); \ 1.466 + memset(dst_argb32_opt, 102, kWidth * BPP_C * kHeight); \ 1.467 + FMT_B##To##FMT_C(dst_argb_c, kStrideB, \ 1.468 + dst_argb32_c, kWidth * BPP_C , \ 1.469 + kWidth, kHeight); \ 1.470 + FMT_B##To##FMT_C(dst_argb_opt, kStrideB, \ 1.471 + dst_argb32_opt, kWidth * BPP_C , \ 1.472 + kWidth, kHeight); \ 1.473 + for (int i = 0; i < kWidth * BPP_C * kHeight; ++i) { \ 1.474 + int abs_diff = \ 1.475 + abs(static_cast<int>(dst_argb32_c[i]) - \ 1.476 + static_cast<int>(dst_argb32_opt[i])); \ 1.477 + if (abs_diff > max_diff) { \ 1.478 + max_diff = abs_diff; \ 1.479 + } \ 1.480 + } \ 1.481 + EXPECT_LE(max_diff, DIFF); \ 1.482 + free_aligned_buffer_64(src_y); \ 1.483 + free_aligned_buffer_64(src_u); \ 1.484 + free_aligned_buffer_64(src_v); \ 1.485 + free_aligned_buffer_64(dst_argb_c); \ 1.486 + free_aligned_buffer_64(dst_argb_opt); \ 1.487 + free_aligned_buffer_64(dst_argb32_c); \ 1.488 + free_aligned_buffer_64(dst_argb32_opt); \ 1.489 +} 1.490 + 1.491 +#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1.492 + YALIGN, DIFF, FMT_C, BPP_C) \ 1.493 + TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1.494 + YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, FMT_C, BPP_C) \ 1.495 + TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1.496 + YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, FMT_C, BPP_C) \ 1.497 + TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1.498 + YALIGN, benchmark_width_, DIFF, _Invert, -, 0, FMT_C, BPP_C) \ 1.499 + TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1.500 + YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C) 1.501 + 1.502 +// TODO(fbarchard): Make vertical alignment unnecessary on bayer. 1.503 +TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4) 1.504 +TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4, 1, 2, ARGB, 4) 1.505 +TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4) 1.506 +TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1, 2, ARGB, 4) 1.507 +TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1, 2, ARGB, 4) 1.508 +TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1, 2, ARGB, 4) 1.509 +TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4) 1.510 +TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2, 1, 9, ARGB, 4) 1.511 +TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2, 1, 17, ARGB, 4) 1.512 +TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 1.513 +TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4, 1, 2, ARGB, 4) 1.514 +TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4) 1.515 +TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4, 1, 2, ARGB, 4) 1.516 +TESTPLANARTOB(I411, 4, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 1.517 +TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 1.518 +TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4, 1, 1, ARGB, 4) 1.519 +TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4, 1, 1, ARGB, 4) 1.520 +TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1, 0, ARGB, 4) 1.521 +TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1, 0, ARGB, 4) 1.522 +TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1, 0, ARGB, 4) 1.523 +TESTPLANARTOB(I420, 2, 2, BayerBGGR, 1, 2, 2, 2, ARGB, 4) 1.524 +TESTPLANARTOB(I420, 2, 2, BayerRGGB, 1, 2, 2, 2, ARGB, 4) 1.525 +TESTPLANARTOB(I420, 2, 2, BayerGBRG, 1, 2, 2, 2, ARGB, 4) 1.526 +TESTPLANARTOB(I420, 2, 2, BayerGRBG, 1, 2, 2, 2, ARGB, 4) 1.527 + 1.528 +#define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 1.529 + W1280, DIFF, N, NEG, OFF) \ 1.530 +TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \ 1.531 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.532 + const int kHeight = benchmark_height_; \ 1.533 + const int kStrideB = kWidth * BPP_B; \ 1.534 + align_buffer_64(src_y, kWidth * kHeight + OFF); \ 1.535 + align_buffer_64(src_uv, \ 1.536 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.537 + SUBSAMPLE(kHeight, SUBSAMP_Y) * 2 + OFF); \ 1.538 + align_buffer_64(dst_argb_c, kStrideB * kHeight); \ 1.539 + align_buffer_64(dst_argb_opt, kStrideB * kHeight); \ 1.540 + srandom(time(NULL)); \ 1.541 + for (int i = 0; i < kHeight; ++i) \ 1.542 + for (int j = 0; j < kWidth; ++j) \ 1.543 + src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \ 1.544 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.545 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) { \ 1.546 + src_uv[(i * SUBSAMPLE(kWidth, SUBSAMP_X)) * 2 + j + OFF] = \ 1.547 + (random() & 0xff); \ 1.548 + } \ 1.549 + } \ 1.550 + memset(dst_argb_c, 1, kStrideB * kHeight); \ 1.551 + memset(dst_argb_opt, 101, kStrideB * kHeight); \ 1.552 + MaskCpuFlags(0); \ 1.553 + FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 1.554 + src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \ 1.555 + dst_argb_c, kWidth * BPP_B, \ 1.556 + kWidth, NEG kHeight); \ 1.557 + MaskCpuFlags(-1); \ 1.558 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.559 + FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 1.560 + src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \ 1.561 + dst_argb_opt, kWidth * BPP_B, \ 1.562 + kWidth, NEG kHeight); \ 1.563 + } \ 1.564 + /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \ 1.565 + align_buffer_64(dst_argb32_c, kWidth * 4 * kHeight); \ 1.566 + align_buffer_64(dst_argb32_opt, kWidth * 4 * kHeight); \ 1.567 + memset(dst_argb32_c, 2, kWidth * 4 * kHeight); \ 1.568 + memset(dst_argb32_opt, 102, kWidth * 4 * kHeight); \ 1.569 + FMT_B##ToARGB(dst_argb_c, kStrideB, \ 1.570 + dst_argb32_c, kWidth * 4, \ 1.571 + kWidth, kHeight); \ 1.572 + FMT_B##ToARGB(dst_argb_opt, kStrideB, \ 1.573 + dst_argb32_opt, kWidth * 4, \ 1.574 + kWidth, kHeight); \ 1.575 + int max_diff = 0; \ 1.576 + for (int i = 0; i < kHeight; ++i) { \ 1.577 + for (int j = 0; j < kWidth * 4; ++j) { \ 1.578 + int abs_diff = \ 1.579 + abs(static_cast<int>(dst_argb32_c[i * kWidth * 4 + j]) - \ 1.580 + static_cast<int>(dst_argb32_opt[i * kWidth * 4 + j])); \ 1.581 + if (abs_diff > max_diff) { \ 1.582 + max_diff = abs_diff; \ 1.583 + } \ 1.584 + } \ 1.585 + } \ 1.586 + EXPECT_LE(max_diff, DIFF); \ 1.587 + free_aligned_buffer_64(src_y); \ 1.588 + free_aligned_buffer_64(src_uv); \ 1.589 + free_aligned_buffer_64(dst_argb_c); \ 1.590 + free_aligned_buffer_64(dst_argb_opt); \ 1.591 + free_aligned_buffer_64(dst_argb32_c); \ 1.592 + free_aligned_buffer_64(dst_argb32_opt); \ 1.593 +} 1.594 + 1.595 +#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, DIFF) \ 1.596 + TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 1.597 + benchmark_width_ - 4, DIFF, _Any, +, 0) \ 1.598 + TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 1.599 + benchmark_width_, DIFF, _Unaligned, +, 1) \ 1.600 + TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 1.601 + benchmark_width_, DIFF, _Invert, -, 0) \ 1.602 + TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 1.603 + benchmark_width_, DIFF, _Opt, +, 0) 1.604 + 1.605 +TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4, 2) 1.606 +TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4, 2) 1.607 +TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9) 1.608 +TESTBIPLANARTOB(NV21, 2, 2, RGB565, 2, 9) 1.609 + 1.610 +#define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.611 + W1280, DIFF, N, NEG, OFF) \ 1.612 +TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \ 1.613 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.614 + const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ 1.615 + const int kStride = \ 1.616 + (SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMP_X * 8 * BPP_A + 7) / 8; \ 1.617 + align_buffer_64(src_argb, kStride * kHeight + OFF); \ 1.618 + align_buffer_64(dst_y_c, kWidth * kHeight); \ 1.619 + align_buffer_64(dst_u_c, \ 1.620 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.621 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.622 + align_buffer_64(dst_v_c, \ 1.623 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.624 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.625 + align_buffer_64(dst_y_opt, kWidth * kHeight); \ 1.626 + align_buffer_64(dst_u_opt, \ 1.627 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.628 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.629 + align_buffer_64(dst_v_opt, \ 1.630 + SUBSAMPLE(kWidth, SUBSAMP_X) * \ 1.631 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.632 + memset(dst_y_c, 1, kWidth * kHeight); \ 1.633 + memset(dst_u_c, 2, \ 1.634 + SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.635 + memset(dst_v_c, 3, \ 1.636 + SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.637 + memset(dst_y_opt, 101, kWidth * kHeight); \ 1.638 + memset(dst_u_opt, 102, \ 1.639 + SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.640 + memset(dst_v_opt, 103, \ 1.641 + SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.642 + srandom(time(NULL)); \ 1.643 + for (int i = 0; i < kHeight; ++i) \ 1.644 + for (int j = 0; j < kStride; ++j) \ 1.645 + src_argb[(i * kStride) + j + OFF] = (random() & 0xff); \ 1.646 + MaskCpuFlags(0); \ 1.647 + FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 1.648 + dst_y_c, kWidth, \ 1.649 + dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.650 + dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.651 + kWidth, NEG kHeight); \ 1.652 + MaskCpuFlags(-1); \ 1.653 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.654 + FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 1.655 + dst_y_opt, kWidth, \ 1.656 + dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.657 + dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1.658 + kWidth, NEG kHeight); \ 1.659 + } \ 1.660 + int max_diff = 0; \ 1.661 + for (int i = 0; i < kHeight; ++i) { \ 1.662 + for (int j = 0; j < kWidth; ++j) { \ 1.663 + int abs_diff = \ 1.664 + abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 1.665 + static_cast<int>(dst_y_opt[i * kWidth + j])); \ 1.666 + if (abs_diff > max_diff) { \ 1.667 + max_diff = abs_diff; \ 1.668 + } \ 1.669 + } \ 1.670 + } \ 1.671 + EXPECT_LE(max_diff, DIFF); \ 1.672 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.673 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 1.674 + int abs_diff = \ 1.675 + abs(static_cast<int>(dst_u_c[i * \ 1.676 + SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 1.677 + static_cast<int>(dst_u_opt[i * \ 1.678 + SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 1.679 + if (abs_diff > max_diff) { \ 1.680 + max_diff = abs_diff; \ 1.681 + } \ 1.682 + } \ 1.683 + } \ 1.684 + EXPECT_LE(max_diff, DIFF); \ 1.685 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.686 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 1.687 + int abs_diff = \ 1.688 + abs(static_cast<int>(dst_v_c[i * \ 1.689 + SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 1.690 + static_cast<int>(dst_v_opt[i * \ 1.691 + SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 1.692 + if (abs_diff > max_diff) { \ 1.693 + max_diff = abs_diff; \ 1.694 + } \ 1.695 + } \ 1.696 + } \ 1.697 + EXPECT_LE(max_diff, DIFF); \ 1.698 + free_aligned_buffer_64(dst_y_c); \ 1.699 + free_aligned_buffer_64(dst_u_c); \ 1.700 + free_aligned_buffer_64(dst_v_c); \ 1.701 + free_aligned_buffer_64(dst_y_opt); \ 1.702 + free_aligned_buffer_64(dst_u_opt); \ 1.703 + free_aligned_buffer_64(dst_v_opt); \ 1.704 + free_aligned_buffer_64(src_argb); \ 1.705 +} 1.706 + 1.707 +#define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.708 + DIFF) \ 1.709 + TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.710 + benchmark_width_ - 4, DIFF, _Any, +, 0) \ 1.711 + TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.712 + benchmark_width_, DIFF, _Unaligned, +, 1) \ 1.713 + TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.714 + benchmark_width_, DIFF, _Invert, -, 0) \ 1.715 + TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.716 + benchmark_width_, DIFF, _Opt, +, 0) 1.717 + 1.718 +TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2, 4) 1.719 +#ifdef __arm__ 1.720 +TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 4) 1.721 +#else 1.722 +TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 0) 1.723 +#endif 1.724 +TESTATOPLANAR(BGRA, 4, 1, I420, 2, 2, 4) 1.725 +TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2, 4) 1.726 +TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2, 4) 1.727 +TESTATOPLANAR(RAW, 3, 1, I420, 2, 2, 4) 1.728 +TESTATOPLANAR(RGB24, 3, 1, I420, 2, 2, 4) 1.729 +TESTATOPLANAR(RGB565, 2, 1, I420, 2, 2, 5) 1.730 +// TODO(fbarchard): Make 1555 neon work same as C code, reduce to diff 9. 1.731 +TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2, 15) 1.732 +TESTATOPLANAR(ARGB4444, 2, 1, I420, 2, 2, 17) 1.733 +TESTATOPLANAR(ARGB, 4, 1, I411, 4, 1, 4) 1.734 +TESTATOPLANAR(ARGB, 4, 1, I422, 2, 1, 2) 1.735 +TESTATOPLANAR(ARGB, 4, 1, I444, 1, 1, 2) 1.736 +TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2, 2) 1.737 +TESTATOPLANAR(UYVY, 2, 1, I420, 2, 2, 2) 1.738 +TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1, 2) 1.739 +TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1, 2) 1.740 +TESTATOPLANAR(I400, 1, 1, I420, 2, 2, 2) 1.741 +TESTATOPLANAR(BayerBGGR, 1, 2, I420, 2, 2, 4) 1.742 +TESTATOPLANAR(BayerRGGB, 1, 2, I420, 2, 2, 4) 1.743 +TESTATOPLANAR(BayerGBRG, 1, 2, I420, 2, 2, 4) 1.744 +TESTATOPLANAR(BayerGRBG, 1, 2, I420, 2, 2, 4) 1.745 + 1.746 +#define TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.747 + W1280, N, NEG, OFF) \ 1.748 +TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \ 1.749 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.750 + const int kHeight = benchmark_height_; \ 1.751 + const int kStride = (kWidth * 8 * BPP_A + 7) / 8; \ 1.752 + align_buffer_64(src_argb, kStride * kHeight + OFF); \ 1.753 + align_buffer_64(dst_y_c, kWidth * kHeight); \ 1.754 + align_buffer_64(dst_uv_c, \ 1.755 + SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \ 1.756 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.757 + align_buffer_64(dst_y_opt, kWidth * kHeight); \ 1.758 + align_buffer_64(dst_uv_opt, \ 1.759 + SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \ 1.760 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.761 + srandom(time(NULL)); \ 1.762 + for (int i = 0; i < kHeight; ++i) \ 1.763 + for (int j = 0; j < kStride; ++j) \ 1.764 + src_argb[(i * kStride) + j + OFF] = (random() & 0xff); \ 1.765 + memset(dst_y_c, 1, kWidth * kHeight); \ 1.766 + memset(dst_uv_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \ 1.767 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.768 + memset(dst_y_opt, 101, kWidth * kHeight); \ 1.769 + memset(dst_uv_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \ 1.770 + SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 1.771 + MaskCpuFlags(0); \ 1.772 + FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 1.773 + dst_y_c, kWidth, \ 1.774 + dst_uv_c, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \ 1.775 + kWidth, NEG kHeight); \ 1.776 + MaskCpuFlags(-1); \ 1.777 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.778 + FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 1.779 + dst_y_opt, kWidth, \ 1.780 + dst_uv_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \ 1.781 + kWidth, NEG kHeight); \ 1.782 + } \ 1.783 + int max_diff = 0; \ 1.784 + for (int i = 0; i < kHeight; ++i) { \ 1.785 + for (int j = 0; j < kWidth; ++j) { \ 1.786 + int abs_diff = \ 1.787 + abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 1.788 + static_cast<int>(dst_y_opt[i * kWidth + j])); \ 1.789 + if (abs_diff > max_diff) { \ 1.790 + max_diff = abs_diff; \ 1.791 + } \ 1.792 + } \ 1.793 + } \ 1.794 + EXPECT_LE(max_diff, 4); \ 1.795 + for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 1.796 + for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) { \ 1.797 + int abs_diff = \ 1.798 + abs(static_cast<int>(dst_uv_c[i * \ 1.799 + SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]) - \ 1.800 + static_cast<int>(dst_uv_opt[i * \ 1.801 + SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j])); \ 1.802 + if (abs_diff > max_diff) { \ 1.803 + max_diff = abs_diff; \ 1.804 + } \ 1.805 + } \ 1.806 + } \ 1.807 + EXPECT_LE(max_diff, 4); \ 1.808 + free_aligned_buffer_64(dst_y_c); \ 1.809 + free_aligned_buffer_64(dst_uv_c); \ 1.810 + free_aligned_buffer_64(dst_y_opt); \ 1.811 + free_aligned_buffer_64(dst_uv_opt); \ 1.812 + free_aligned_buffer_64(src_argb); \ 1.813 +} 1.814 + 1.815 +#define TESTATOBIPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 1.816 + TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.817 + benchmark_width_ - 4, _Any, +, 0) \ 1.818 + TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.819 + benchmark_width_, _Unaligned, +, 1) \ 1.820 + TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.821 + benchmark_width_, _Invert, -, 0) \ 1.822 + TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 1.823 + benchmark_width_, _Opt, +, 0) 1.824 + 1.825 +TESTATOBIPLANAR(ARGB, 4, NV12, 2, 2) 1.826 +TESTATOBIPLANAR(ARGB, 4, NV21, 2, 2) 1.827 + 1.828 +#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.829 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1.830 + W1280, DIFF, N, NEG, OFF) \ 1.831 +TEST_F(libyuvTest, FMT_A##To##FMT_B##N) { \ 1.832 + const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1.833 + const int kHeight = benchmark_height_; \ 1.834 + const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \ 1.835 + const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \ 1.836 + const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \ 1.837 + const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \ 1.838 + align_buffer_64(src_argb, kStrideA * kHeightA + OFF); \ 1.839 + align_buffer_64(dst_argb_c, kStrideB * kHeightB); \ 1.840 + align_buffer_64(dst_argb_opt, kStrideB * kHeightB); \ 1.841 + srandom(time(NULL)); \ 1.842 + for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 1.843 + src_argb[i + OFF] = (random() & 0xff); \ 1.844 + } \ 1.845 + memset(dst_argb_c, 1, kStrideB * kHeightB); \ 1.846 + memset(dst_argb_opt, 101, kStrideB * kHeightB); \ 1.847 + MaskCpuFlags(0); \ 1.848 + FMT_A##To##FMT_B(src_argb + OFF, kStrideA, \ 1.849 + dst_argb_c, kStrideB, \ 1.850 + kWidth, NEG kHeight); \ 1.851 + MaskCpuFlags(-1); \ 1.852 + for (int i = 0; i < benchmark_iterations_; ++i) { \ 1.853 + FMT_A##To##FMT_B(src_argb + OFF, kStrideA, \ 1.854 + dst_argb_opt, kStrideB, \ 1.855 + kWidth, NEG kHeight); \ 1.856 + } \ 1.857 + int max_diff = 0; \ 1.858 + for (int i = 0; i < kStrideB * kHeightB; ++i) { \ 1.859 + int abs_diff = \ 1.860 + abs(static_cast<int>(dst_argb_c[i]) - \ 1.861 + static_cast<int>(dst_argb_opt[i])); \ 1.862 + if (abs_diff > max_diff) { \ 1.863 + max_diff = abs_diff; \ 1.864 + } \ 1.865 + } \ 1.866 + EXPECT_LE(max_diff, DIFF); \ 1.867 + free_aligned_buffer_64(src_argb); \ 1.868 + free_aligned_buffer_64(dst_argb_c); \ 1.869 + free_aligned_buffer_64(dst_argb_opt); \ 1.870 +} 1.871 + 1.872 +#define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.873 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \ 1.874 +TEST_F(libyuvTest, FMT_A##To##FMT_B##_Random) { \ 1.875 + srandom(time(NULL)); \ 1.876 + for (int times = 0; times < benchmark_iterations_; ++times) { \ 1.877 + const int kWidth = (random() & 63) + 1; \ 1.878 + const int kHeight = (random() & 31) + 1; \ 1.879 + const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \ 1.880 + const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \ 1.881 + const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;\ 1.882 + const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;\ 1.883 + align_buffer_page_end(src_argb, kStrideA * kHeightA); \ 1.884 + align_buffer_page_end(dst_argb_c, kStrideB * kHeightB); \ 1.885 + align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB); \ 1.886 + for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 1.887 + src_argb[i] = (random() & 0xff); \ 1.888 + } \ 1.889 + memset(dst_argb_c, 123, kStrideB * kHeightB); \ 1.890 + memset(dst_argb_opt, 123, kStrideB * kHeightB); \ 1.891 + MaskCpuFlags(0); \ 1.892 + FMT_A##To##FMT_B(src_argb, kStrideA, \ 1.893 + dst_argb_c, kStrideB, \ 1.894 + kWidth, kHeight); \ 1.895 + MaskCpuFlags(-1); \ 1.896 + FMT_A##To##FMT_B(src_argb, kStrideA, \ 1.897 + dst_argb_opt, kStrideB, \ 1.898 + kWidth, kHeight); \ 1.899 + int max_diff = 0; \ 1.900 + for (int i = 0; i < kStrideB * kHeightB; ++i) { \ 1.901 + int abs_diff = \ 1.902 + abs(static_cast<int>(dst_argb_c[i]) - \ 1.903 + static_cast<int>(dst_argb_opt[i])); \ 1.904 + if (abs_diff > max_diff) { \ 1.905 + max_diff = abs_diff; \ 1.906 + } \ 1.907 + } \ 1.908 + EXPECT_LE(max_diff, DIFF); \ 1.909 + free_aligned_buffer_page_end(src_argb); \ 1.910 + free_aligned_buffer_page_end(dst_argb_c); \ 1.911 + free_aligned_buffer_page_end(dst_argb_opt); \ 1.912 + } \ 1.913 +} 1.914 + 1.915 +#define TESTATOB(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.916 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \ 1.917 + TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.918 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1.919 + benchmark_width_ - 4, DIFF, _Any, +, 0) \ 1.920 + TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.921 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1.922 + benchmark_width_, DIFF, _Unaligned, +, 1) \ 1.923 + TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.924 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1.925 + benchmark_width_, DIFF, _Invert, -, 0) \ 1.926 + TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.927 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1.928 + benchmark_width_, DIFF, _Opt, +, 0) \ 1.929 + TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1.930 + FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) 1.931 + 1.932 +TESTATOB(ARGB, 4, 4, 1, ARGB, 4, 4, 1, 0) 1.933 +TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0) 1.934 +TESTATOB(ARGB, 4, 4, 1, ABGR, 4, 4, 1, 0) 1.935 +TESTATOB(ARGB, 4, 4, 1, RGBA, 4, 4, 1, 0) 1.936 +TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0) 1.937 +TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0) 1.938 +TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0) 1.939 +TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0) 1.940 +TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0) 1.941 +TESTATOB(ARGB, 4, 4, 1, BayerBGGR, 1, 1, 1, 0) 1.942 +TESTATOB(ARGB, 4, 4, 1, BayerRGGB, 1, 1, 1, 0) 1.943 +TESTATOB(ARGB, 4, 4, 1, BayerGBRG, 1, 1, 1, 0) 1.944 +TESTATOB(ARGB, 4, 4, 1, BayerGRBG, 1, 1, 1, 0) 1.945 +TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4) 1.946 +TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4) 1.947 +TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2) 1.948 +TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2) 1.949 +TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0) 1.950 +TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0) 1.951 +TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0) 1.952 +TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1, 0) 1.953 +TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1, 0) 1.954 +TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0) 1.955 +TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0) 1.956 +TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0) 1.957 +TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, 4) 1.958 +TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, 4) 1.959 +TESTATOB(BayerBGGR, 1, 2, 2, ARGB, 4, 4, 1, 0) 1.960 +TESTATOB(BayerRGGB, 1, 2, 2, ARGB, 4, 4, 1, 0) 1.961 +TESTATOB(BayerGBRG, 1, 2, 2, ARGB, 4, 4, 1, 0) 1.962 +TESTATOB(BayerGRBG, 1, 2, 2, ARGB, 4, 4, 1, 0) 1.963 +TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0) 1.964 +TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1, 0) 1.965 +TESTATOB(I400, 1, 1, 1, I400Mirror, 1, 1, 1, 0) 1.966 +TESTATOB(Y, 1, 1, 1, ARGB, 4, 4, 1, 0) 1.967 +TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0) 1.968 + 1.969 +TEST_F(libyuvTest, Test565) { 1.970 + SIMD_ALIGNED(uint8 orig_pixels[256][4]); 1.971 + SIMD_ALIGNED(uint8 pixels565[256][2]); 1.972 + 1.973 + for (int i = 0; i < 256; ++i) { 1.974 + for (int j = 0; j < 4; ++j) { 1.975 + orig_pixels[i][j] = i; 1.976 + } 1.977 + } 1.978 + ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1); 1.979 + uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381); 1.980 + EXPECT_EQ(610919429u, checksum); 1.981 +} 1.982 + 1.983 +#ifdef HAVE_JPEG 1.984 +TEST_F(libyuvTest, ValidateJpeg) { 1.985 + const int kOff = 10; 1.986 + const int kMinJpeg = 64; 1.987 + const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ? 1.988 + benchmark_width_ * benchmark_height_ : kMinJpeg; 1.989 + const int kSize = kImageSize + kOff; 1.990 + align_buffer_64(orig_pixels, kSize); 1.991 + 1.992 + // No SOI or EOI. Expect fail. 1.993 + memset(orig_pixels, 0, kSize); 1.994 + 1.995 + // EOI, SOI. Expect pass. 1.996 + orig_pixels[0] = 0xff; 1.997 + orig_pixels[1] = 0xd8; // SOI. 1.998 + orig_pixels[kSize - kOff + 0] = 0xff; 1.999 + orig_pixels[kSize - kOff + 1] = 0xd9; // EOI. 1.1000 + for (int times = 0; times < benchmark_iterations_; ++times) { 1.1001 + EXPECT_TRUE(ValidateJpeg(orig_pixels, kSize)); 1.1002 + } 1.1003 + free_aligned_buffer_page_end(orig_pixels); 1.1004 +} 1.1005 + 1.1006 +TEST_F(libyuvTest, InvalidateJpeg) { 1.1007 + const int kOff = 10; 1.1008 + const int kMinJpeg = 64; 1.1009 + const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ? 1.1010 + benchmark_width_ * benchmark_height_ : kMinJpeg; 1.1011 + const int kSize = kImageSize + kOff; 1.1012 + align_buffer_64(orig_pixels, kSize); 1.1013 + 1.1014 + // No SOI or EOI. Expect fail. 1.1015 + memset(orig_pixels, 0, kSize); 1.1016 + EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1.1017 + 1.1018 + // SOI but no EOI. Expect fail. 1.1019 + orig_pixels[0] = 0xff; 1.1020 + orig_pixels[1] = 0xd8; // SOI. 1.1021 + for (int times = 0; times < benchmark_iterations_; ++times) { 1.1022 + EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1.1023 + } 1.1024 + // EOI but no SOI. Expect fail. 1.1025 + orig_pixels[0] = 0; 1.1026 + orig_pixels[1] = 0; 1.1027 + orig_pixels[kSize - kOff + 0] = 0xff; 1.1028 + orig_pixels[kSize - kOff + 1] = 0xd9; // EOI. 1.1029 + EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1.1030 + 1.1031 + free_aligned_buffer_page_end(orig_pixels); 1.1032 +} 1.1033 + 1.1034 +#endif 1.1035 + 1.1036 +} // namespace libyuv