rotate_test.cc 40.5 KB
Newer Older
1
/*
2
 *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 4 5 6
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS. All contributing project authors may
8 9 10 11
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <stdlib.h>
12
#include <time.h>
13

14
#include "libyuv/rotate.h"
15
#include "../unit_test/unit_test.h"
16
#include "libyuv/cpu_id.h"
frkoenig@google.com's avatar
frkoenig@google.com committed
17

mikhal@webrtc.org's avatar
mikhal@webrtc.org committed
18
namespace libyuv {
19

20 21 22 23 24
void PrintArray(uint8 *array, int w, int h) {
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      printf("%4d", (signed char)array[i * w + j]);
    }
25 26 27 28 29 30 31
    printf("\n");
  }
}

TEST_F(libyuvTest, Transpose) {
  int iw, ih, ow, oh;
  int err = 0;
32 33 34 35 36 37
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;
  ow = ih;
  oh = iw;

38 39 40
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_1, ow * oh)
  align_buffer_64(output_2, iw * ih)
41 42 43 44

  for (i = 0; i < iw * ih; ++i) {
    input[i] = i;
  }
45

46 47
  TransposePlane(input,    iw, output_1, ow, iw, ih);
  TransposePlane(output_1, ow, output_2, oh, ow, oh);
48

49 50 51 52 53
  for (i = 0; i < iw * ih; ++i) {
    if (input[i] != output_2[i]) {
      err++;
    }
  }
54

55 56 57
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);
58

59 60
    printf("transpose 1\n");
    PrintArray(output_1, ow, oh);
61

62 63
    printf("transpose 2\n");
    PrintArray(output_2, iw, ih);
64
  }
65

66 67 68
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_1)
  free_aligned_buffer_64(output_2)
69

70 71 72
  EXPECT_EQ(0, err);
}

73 74 75
TEST_F(libyuvTest, TransposeUV) {
  int iw, ih, ow, oh;
  int err = 0;
76 77 78 79 80
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;

  ow = ih;
81
  oh = iw;
82

83
  align_buffer_64(input, 2 * iw * ih)
84 85 86 87
  align_buffer_64(output_a1, ow * oh)
  align_buffer_64(output_b1, ow * oh)
  align_buffer_64(output_a2, iw * ih)
  align_buffer_64(output_b2, iw * ih)
88

89
  for (i = 0; i < 2 * iw * ih; i += 2) {
90 91 92 93
    input[i] = i >> 1;
    input[i + 1] = -(i >> 1);
  }

94
  TransposeUV(input, iw * 2, output_a1, ow, output_b1, ow, iw, ih);
95

96 97 98
  TransposePlane(output_a1, ow, output_a2, oh, ow, oh);
  TransposePlane(output_b1, ow, output_b2, oh, ow, oh);

99
  for (i = 0; i < 2 * iw * ih; i += 2) {
100 101 102 103 104
    if (input[i] != output_a2[i >> 1]) {
      err++;
    }
    if (input[i + 1] != output_b2[i >> 1]) {
      err++;
105
    }
106
  }
107

108 109 110 111 112 113 114 115 116 117 118 119 120
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);

    printf("transpose 1\n");
    PrintArray(output_a1, ow, oh);
    PrintArray(output_b1, ow, oh);

    printf("transpose 2\n");
    PrintArray(output_a2, oh, ow);
    PrintArray(output_b2, oh, ow);
  }

121 122 123 124 125
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_a1)
  free_aligned_buffer_64(output_b1)
  free_aligned_buffer_64(output_a2)
  free_aligned_buffer_64(output_b2)
126

127 128 129 130
  EXPECT_EQ(0, err);
}

TEST_F(libyuvTest, RotatePlane90) {
131 132
  int iw, ih, ow, oh;
  int err = 0;
133 134 135
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;
136

137 138
  ow = ih;
  oh = iw;
139

140 141 142 143 144
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0, iw * ih)
  align_buffer_64(output_90, ow * oh)
  align_buffer_64(output_180, iw * ih)
  align_buffer_64(output_270, ow * oh)
145

146 147 148
  for (i = 0; i < iw * ih; ++i) {
    input[i] = i;
  }
149

150 151 152 153
  RotatePlane90(input,      iw, output_90,  ow, iw, ih);
  RotatePlane90(output_90,  ow, output_180, oh, ow, oh);
  RotatePlane90(output_180, oh, output_270, ow, oh, ow);
  RotatePlane90(output_270, ow, output_0,   iw, ow, oh);
154

155 156 157 158 159
  for (i = 0; i < iw * ih; ++i) {
    if (input[i] != output_0[i]) {
      err++;
    }
  }
160

161 162 163
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);
164

165 166
    printf("output 90\n");
    PrintArray(output_90, ow, oh);
167

168 169
    printf("output 180\n");
    PrintArray(output_180, iw, ih);
170

171 172
    printf("output 270\n");
    PrintArray(output_270, ow, oh);
173

174 175
    printf("output 0\n");
    PrintArray(output_0, iw, ih);
176
  }
177

178 179 180 181 182
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0)
  free_aligned_buffer_64(output_90)
  free_aligned_buffer_64(output_180)
  free_aligned_buffer_64(output_270)
183

184 185 186
  EXPECT_EQ(0, err);
}

187
TEST_F(libyuvTest, RotateUV90) {
188 189
  int iw, ih, ow, oh;
  int err = 0;
190 191 192 193 194
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;

  ow = ih;
195
  oh = (iw + 1) / 2;
196

197 198 199 200 201 202 203
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0_u, ow * oh)
  align_buffer_64(output_0_v, ow * oh)
  align_buffer_64(output_90_u, ow * oh)
  align_buffer_64(output_90_v, ow * oh)
  align_buffer_64(output_180_u, ow * oh)
  align_buffer_64(output_180_v, ow * oh)
204 205 206 207 208 209

  for (i = 0; i < iw * ih; i += 2) {
    input[i] = i >> 1;
    input[i + 1] = -(i >> 1);
  }

210
  RotateUV90(input, iw, output_90_u, ow, output_90_v, ow, (iw + 1) / 2, ih);
211 212 213

  RotatePlane90(output_90_u, ow, output_180_u, oh, ow, oh);
  RotatePlane90(output_90_v, ow, output_180_v, oh, ow, oh);
214

215 216 217 218 219 220 221 222 223
  RotatePlane180(output_180_u, ow, output_0_u, ow, ow, oh);
  RotatePlane180(output_180_v, ow, output_0_v, ow, ow, oh);

  for (i = 0; i < (ow * oh); ++i) {
    if (output_0_u[i] != (uint8)i) {
      err++;
    }
    if (output_0_v[i] != (uint8)(-i)) {
      err++;
224
    }
225
  }
226

227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);

    printf("output 90_u\n");
    PrintArray(output_90_u, ow, oh);

    printf("output 90_v\n");
    PrintArray(output_90_v, ow, oh);

    printf("output 180_u\n");
    PrintArray(output_180_u, oh, ow);

    printf("output 180_v\n");
    PrintArray(output_180_v, oh, ow);

    printf("output 0_u\n");
    PrintArray(output_0_u, oh, ow);

    printf("output 0_v\n");
    PrintArray(output_0_v, oh, ow);
  }

250 251 252 253 254 255 256
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0_u)
  free_aligned_buffer_64(output_0_v)
  free_aligned_buffer_64(output_90_u)
  free_aligned_buffer_64(output_90_v)
  free_aligned_buffer_64(output_180_u)
  free_aligned_buffer_64(output_180_v)
257

258 259 260
  EXPECT_EQ(0, err);
}

261
TEST_F(libyuvTest, RotateUV180) {
262 263
  int iw, ih, ow, oh;
  int err = 0;
264 265 266 267
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;

268
  ow = (iw + 1) / 2;
269 270
  oh = ih;

271 272 273 274 275 276 277
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0_u, ow * oh)
  align_buffer_64(output_0_v, ow * oh)
  align_buffer_64(output_90_u, ow * oh)
  align_buffer_64(output_90_v, ow * oh)
  align_buffer_64(output_180_u, ow * oh)
  align_buffer_64(output_180_v, ow * oh)
278 279 280 281 282 283

  for (i = 0; i < iw * ih; i += 2) {
    input[i] = i >> 1;
    input[i + 1] = -(i >> 1);
  }

284
  RotateUV180(input, iw, output_180_u, ow, output_180_v, ow, (iw + 1) / 2, ih);
285 286 287

  RotatePlane90(output_180_u, ow, output_90_u, oh, ow, oh);
  RotatePlane90(output_180_v, ow, output_90_v, oh, ow, oh);
288

289 290 291 292 293 294 295 296 297
  RotatePlane90(output_90_u, oh, output_0_u, ow, oh, ow);
  RotatePlane90(output_90_v, oh, output_0_v, ow, oh, ow);

  for (i = 0; i < (ow * oh); ++i) {
    if (output_0_u[i] != (uint8)i) {
      err++;
    }
    if (output_0_v[i] != (uint8)(-i)) {
      err++;
298
    }
299
  }
300

301 302 303
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);
304

305 306
    printf("output 180_u\n");
    PrintArray(output_180_u, oh, ow);
307

308 309 310 311 312 313 314 315 316 317 318 319 320 321
    printf("output 180_v\n");
    PrintArray(output_180_v, oh, ow);

    printf("output 90_u\n");
    PrintArray(output_90_u, oh, ow);

    printf("output 90_v\n");
    PrintArray(output_90_v, oh, ow);

    printf("output 0_u\n");
    PrintArray(output_0_u, ow, oh);

    printf("output 0_v\n");
    PrintArray(output_0_v, ow, oh);
322
  }
323

324 325 326 327 328 329 330
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0_u)
  free_aligned_buffer_64(output_0_v)
  free_aligned_buffer_64(output_90_u)
  free_aligned_buffer_64(output_90_v)
  free_aligned_buffer_64(output_180_u)
  free_aligned_buffer_64(output_180_v)
331

332 333 334
  EXPECT_EQ(0, err);
}

335
TEST_F(libyuvTest, RotateUV270) {
336 337
  int iw, ih, ow, oh;
  int err = 0;
338 339 340 341 342
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;

  ow = ih;
343
  oh = (iw + 1) / 2;
344

345 346 347 348 349 350 351
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0_u, ow * oh)
  align_buffer_64(output_0_v, ow * oh)
  align_buffer_64(output_270_u, ow * oh)
  align_buffer_64(output_270_v, ow * oh)
  align_buffer_64(output_180_u, ow * oh)
  align_buffer_64(output_180_v, ow * oh)
352 353 354 355 356

  for (i = 0; i < iw * ih; i += 2) {
    input[i] = i >> 1;
    input[i + 1] = -(i >> 1);
  }
357

358
  RotateUV270(input, iw, output_270_u, ow, output_270_v, ow,
359
                   (iw + 1) / 2, ih);
360

361 362
  RotatePlane270(output_270_u, ow, output_180_u, oh, ow, oh);
  RotatePlane270(output_270_v, ow, output_180_v, oh, ow, oh);
363

364 365
  RotatePlane180(output_180_u, ow, output_0_u, ow, ow, oh);
  RotatePlane180(output_180_v, ow, output_0_v, ow, ow, oh);
366

367 368 369 370 371 372 373 374
  for (i = 0; i < (ow * oh); ++i) {
    if (output_0_u[i] != (uint8)i) {
      err++;
    }
    if (output_0_v[i] != (uint8)(-i)) {
      err++;
    }
  }
375

376 377 378
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);
379

380 381
    printf("output 270_u\n");
    PrintArray(output_270_u, ow, oh);
382

383 384
    printf("output 270_v\n");
    PrintArray(output_270_v, ow, oh);
385

386 387
    printf("output 180_u\n");
    PrintArray(output_180_u, oh, ow);
388

389 390
    printf("output 180_v\n");
    PrintArray(output_180_v, oh, ow);
391

392 393 394 395 396 397 398
    printf("output 0_u\n");
    PrintArray(output_0_u, oh, ow);

    printf("output 0_v\n");
    PrintArray(output_0_v, oh, ow);
  }

399 400 401 402 403 404 405
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0_u)
  free_aligned_buffer_64(output_0_v)
  free_aligned_buffer_64(output_270_u)
  free_aligned_buffer_64(output_270_v)
  free_aligned_buffer_64(output_180_u)
  free_aligned_buffer_64(output_180_v)
406 407 408 409

  EXPECT_EQ(0, err);
}

410
TEST_F(libyuvTest, RotatePlane180) {
411 412
  int iw, ih, ow, oh;
  int err = 0;
413 414 415
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;
416

417 418
  ow = iw;
  oh = ih;
419

420 421 422
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0, iw * ih)
  align_buffer_64(output_180, iw * ih)
423

424 425 426
  for (i = 0; i < iw * ih; ++i) {
    input[i] = i;
  }
427

428 429
  RotatePlane180(input,      iw, output_180, ow, iw, ih);
  RotatePlane180(output_180, ow, output_0,   iw, ow, oh);
430

431 432 433 434 435
  for (i = 0; i < iw * ih; ++i) {
    if (input[i] != output_0[i]) {
      err++;
    }
  }
436

437 438 439
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);
440

441 442
    printf("output 180\n");
    PrintArray(output_180, iw, ih);
443

444 445 446
    printf("output 0\n");
    PrintArray(output_0, iw, ih);
  }
447

448 449 450
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0)
  free_aligned_buffer_64(output_180)
451

452 453
  EXPECT_EQ(0, err);
}
454

455 456 457 458 459 460 461 462 463 464
TEST_F(libyuvTest, RotatePlane270) {
  int iw, ih, ow, oh;
  int err = 0;
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;

  ow = ih;
  oh = iw;

465 466 467 468 469
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0, iw * ih)
  align_buffer_64(output_90, ow * oh)
  align_buffer_64(output_180, iw * ih)
  align_buffer_64(output_270, ow * oh)
470 471 472 473 474 475 476 477 478 479 480 481

  for (i = 0; i < iw * ih; ++i)
    input[i] = i;

  RotatePlane270(input,      iw, output_270, ow, iw, ih);
  RotatePlane270(output_270, ow, output_180, oh, ow, oh);
  RotatePlane270(output_180, oh, output_90,  ow, oh, ow);
  RotatePlane270(output_90,  ow, output_0,   iw, ow, oh);

  for (i = 0; i < iw * ih; ++i) {
    if (input[i] != output_0[i]) {
      err++;
482
    }
483
  }
484

485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
  if (err) {
    printf("input %dx%d \n", iw, ih);
    PrintArray(input, iw, ih);

    printf("output 270\n");
    PrintArray(output_270, ow, oh);

    printf("output 180\n");
    PrintArray(output_180, iw, ih);

    printf("output 90\n");
    PrintArray(output_90, ow, oh);

    printf("output 0\n");
    PrintArray(output_0, iw, ih);
  }

502 503 504 505 506
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0)
  free_aligned_buffer_64(output_90)
  free_aligned_buffer_64(output_180)
  free_aligned_buffer_64(output_270)
507

508 509 510
  EXPECT_EQ(0, err);
}

511
TEST_F(libyuvTest, RotatePlane90and270) {
512 513
  int iw, ih, ow, oh;
  int err = 0;
514 515 516
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;
517

518 519
  ow = ih;
  oh = iw;
520

521 522 523
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0, iw * ih)
  align_buffer_64(output_90, ow * oh)
524

525 526 527
  for (i = 0; i < iw * ih; ++i) {
    input[i] = i;
  }
528

529 530
  RotatePlane90(input,      iw, output_90,  ow, iw, ih);
  RotatePlane270(output_90, ow, output_0,   iw, ow, oh);
531

532 533 534 535 536
  for (i = 0; i < iw * ih; ++i) {
    if (input[i] != output_0[i]) {
      err++;
    }
  }
537

538 539 540
  if (err) {
    printf("intput %dx%d\n", iw, ih);
    PrintArray(input, iw, ih);
541

542 543
    printf("output \n");
    PrintArray(output_90, ow, oh);
544

545 546 547
    printf("output \n");
    PrintArray(output_0, iw, ih);
  }
548

549 550 551
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0)
  free_aligned_buffer_64(output_90)
552 553 554 555

  EXPECT_EQ(0, err);
}

556 557
TEST_F(libyuvTest, RotatePlane90Pitch) {
  int iw, ih;
558
  int err = 0;
559 560 561 562 563 564
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;

  int ow = ih;
  int oh = iw;
565

566 567 568
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0, iw * ih)
  align_buffer_64(output_90, ow * oh)
569 570 571 572 573 574

  for (i = 0; i < iw * ih; ++i) {
    input[i] = i;
  }

  RotatePlane90(input, iw,
575 576 577 578 579 580
                output_90 + (ow + 1) / 2, ow,
                (iw + 1) / 2, (ih + 1) / 2);
  RotatePlane90(input + ((iw + 1) / 2), iw,
                output_90 + (ow + 1) / 2 + ow * ((oh + 1) / 2), ow,
                (iw + 1) / 2, (ih + 1) / 2);
  RotatePlane90(input + iw * ((ih + 1) / 2), iw,
581
                output_90, ow,
582 583 584 585
                (iw + 1) / 2, (ih + 1) / 2);
  RotatePlane90(input + ((iw + 1) / 2) + iw * ((ih + 1) / 2), iw,
                output_90 + ow * ((oh + 1) / 2), ow,
                (iw + 1) / 2, (ih + 1) / 2);
586 587 588 589 590 591

  RotatePlane270(output_90, ih, output_0,   iw, ow, oh);

  for (i = 0; i < iw * ih; ++i) {
    if (input[i] != output_0[i]) {
      err++;
592
    }
593 594 595 596 597 598 599 600 601 602 603 604 605
  }

  if (err) {
    printf("intput %dx%d\n", iw, ih);
    PrintArray(input, iw, ih);

    printf("output \n");
    PrintArray(output_90, ow, oh);

    printf("output \n");
    PrintArray(output_0, iw, ih);
  }

606 607 608
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0)
  free_aligned_buffer_64(output_90)
609 610 611 612

  EXPECT_EQ(0, err);
}

613
TEST_F(libyuvTest, RotatePlane270Pitch) {
614 615
  int iw, ih, ow, oh;
  int err = 0;
616 617 618
  iw = benchmark_width_;
  ih = benchmark_height_;
  int i;
619

620 621 622
  ow = ih;
  oh = iw;

623 624 625
  align_buffer_64(input, iw * ih)
  align_buffer_64(output_0, iw * ih)
  align_buffer_64(output_270, ow * oh)
626 627 628 629 630 631

  for (i = 0; i < iw * ih; ++i) {
    input[i] = i;
  }

  RotatePlane270(input, iw,
632 633 634
                 output_270 + ow * ((oh + 1) / 2), ow,
                 (iw + 1) / 2, (ih + 1) / 2);
  RotatePlane270(input + ((iw + 1) / 2), iw,
635
                 output_270, ow,
636 637 638 639 640 641 642
                 (iw + 1) / 2, (ih + 1) / 2);
  RotatePlane270(input + iw * ((ih + 1) / 2), iw,
                 output_270 + (ow + 1) / 2 + ow * ((oh + 1) / 2), ow,
                 (iw + 1) / 2, (ih + 1) / 2);
  RotatePlane270(input + ((iw + 1) / 2) + iw * ((ih + 1) / 2), iw,
                 output_270 + (ow + 1) / 2, ow,
                 (iw + 1) / 2, (ih + 1) / 2);
643 644 645 646 647 648

  RotatePlane90(output_270, ih, output_0,   iw, ow, oh);

  for (i = 0; i < iw * ih; ++i) {
    if (input[i] != output_0[i]) {
      err++;
649
    }
650
  }
651

652 653 654 655 656 657 658 659 660 661 662
  if (err) {
    printf("intput %dx%d\n", iw, ih);
    PrintArray(input, iw, ih);

    printf("output \n");
    PrintArray(output_270, ow, oh);

    printf("output \n");
    PrintArray(output_0, iw, ih);
  }

663 664 665
  free_aligned_buffer_64(input)
  free_aligned_buffer_64(output_0)
  free_aligned_buffer_64(output_270)
666

667 668
  EXPECT_EQ(0, err);
}
669 670 671 672

TEST_F(libyuvTest, I420Rotate90) {
  int err = 0;

673 674
  int yw = benchmark_width_;
  int yh = benchmark_height_;
675
  int b = 128;
676 677
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
678 679 680

  int i, j;

681 682
  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
683 684 685

  srandom(time(NULL));

686 687 688 689 690 691 692 693 694 695 696 697
  align_buffer_64(orig_y, y_plane_size)
  align_buffer_64(orig_u, uv_plane_size)
  align_buffer_64(orig_v, uv_plane_size)
  align_buffer_64(ro0_y, y_plane_size)
  align_buffer_64(ro0_u, uv_plane_size)
  align_buffer_64(ro0_v, uv_plane_size)
  align_buffer_64(ro90_y, y_plane_size)
  align_buffer_64(ro90_u, uv_plane_size)
  align_buffer_64(ro90_v, uv_plane_size)
  align_buffer_64(ro270_y, y_plane_size)
  align_buffer_64(ro270_u, uv_plane_size)
  align_buffer_64(ro270_v, uv_plane_size)
698 699 700 701 702 703 704 705 706 707 708 709
  memset(orig_y, 0, y_plane_size);
  memset(orig_u, 0, uv_plane_size);
  memset(orig_v, 0, uv_plane_size);
  memset(ro0_y, 0, y_plane_size);
  memset(ro0_u, 0, uv_plane_size);
  memset(ro0_v, 0, uv_plane_size);
  memset(ro90_y, 0, y_plane_size);
  memset(ro90_u, 0, uv_plane_size);
  memset(ro90_v, 0, uv_plane_size);
  memset(ro270_y, 0, y_plane_size);
  memset(ro270_u, 0, uv_plane_size);
  memset(ro270_v, 0, uv_plane_size);
710 711 712 713

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
714
      orig_y[i * (yw + b * 2) + j] = random() & 0xff;
715 716 717 718 719
    }
  }

  for (i = b; i < (uvh + b); ++i) {
    for (j = b; j < (uvw + b); ++j) {
720 721
      orig_u[i * (uvw + b * 2) + j] = random() & 0xff;
      orig_v[i * (uvw + b * 2) + j] = random() & 0xff;
722 723 724
    }
  }

725 726 727 728
  int y_off_0 = b * (yw + b * 2) + b;
  int uv_off_0 = b * (uvw + b * 2) + b;
  int y_off_90 = b * (yh + b * 2) + b;
  int uv_off_90 = b * (uvh + b * 2) + b;
729

730 731 732 733
  int y_st_0 = yw + b * 2;
  int uv_st_0 = uvw + b * 2;
  int y_st_90 = yh + b * 2;
  int uv_st_90 = uvh + b * 2;
734

735 736 737 738 739 740
  I420Rotate(orig_y + y_off_0, y_st_0,
             orig_u + uv_off_0, uv_st_0,
             orig_v + uv_off_0, uv_st_0,
             ro90_y + y_off_90, y_st_90,
             ro90_u + uv_off_90, uv_st_90,
             ro90_v + uv_off_90, uv_st_90,
741 742 743
             yw, yh,
             kRotateClockwise);

744 745 746 747 748 749
  I420Rotate(ro90_y + y_off_90, y_st_90,
             ro90_u + uv_off_90, uv_st_90,
             ro90_v + uv_off_90, uv_st_90,
             ro270_y + y_off_90, y_st_90,
             ro270_u + uv_off_90, uv_st_90,
             ro270_v + uv_off_90, uv_st_90,
750 751 752
             yh, yw,
             kRotate180);

753 754 755 756 757 758
  I420Rotate(ro270_y + y_off_90, y_st_90,
             ro270_u + uv_off_90, uv_st_90,
             ro270_v + uv_off_90, uv_st_90,
             ro0_y + y_off_0, y_st_0,
             ro0_u + uv_off_0, uv_st_0,
             ro0_v + uv_off_0, uv_st_0,
759 760 761 762
             yh, yw,
             kRotateClockwise);

  for (i = 0; i < y_plane_size; ++i) {
763
    if (orig_y[i] != ro0_y[i]) {
764
      ++err;
765
    }
766 767 768
  }

  for (i = 0; i < uv_plane_size; ++i) {
769
    if (orig_u[i] != ro0_u[i]) {
770
      ++err;
771 772
    }
    if (orig_v[i] != ro0_v[i]) {
773
      ++err;
774
    }
775 776
  }

777 778 779 780 781 782 783 784 785 786 787 788
  free_aligned_buffer_64(orig_y)
  free_aligned_buffer_64(orig_u)
  free_aligned_buffer_64(orig_v)
  free_aligned_buffer_64(ro0_y)
  free_aligned_buffer_64(ro0_u)
  free_aligned_buffer_64(ro0_v)
  free_aligned_buffer_64(ro90_y)
  free_aligned_buffer_64(ro90_u)
  free_aligned_buffer_64(ro90_v)
  free_aligned_buffer_64(ro270_y)
  free_aligned_buffer_64(ro270_u)
  free_aligned_buffer_64(ro270_v)
789 790 791 792 793 794 795

  EXPECT_EQ(0, err);
}

TEST_F(libyuvTest, I420Rotate270) {
  int err = 0;

796 797
  int yw = benchmark_width_;
  int yh = benchmark_height_;
798
  int b = 128;
799 800
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
801 802 803

  int i, j;

804 805
  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
806 807 808

  srandom(time(NULL));

809 810 811 812 813 814 815 816 817 818 819 820
  align_buffer_64(orig_y, y_plane_size)
  align_buffer_64(orig_u, uv_plane_size)
  align_buffer_64(orig_v, uv_plane_size)
  align_buffer_64(ro0_y, y_plane_size)
  align_buffer_64(ro0_u, uv_plane_size)
  align_buffer_64(ro0_v, uv_plane_size)
  align_buffer_64(ro90_y, y_plane_size)
  align_buffer_64(ro90_u, uv_plane_size)
  align_buffer_64(ro90_v, uv_plane_size)
  align_buffer_64(ro270_y, y_plane_size)
  align_buffer_64(ro270_u, uv_plane_size)
  align_buffer_64(ro270_v, uv_plane_size)
821 822 823 824 825 826 827 828 829 830 831 832
  memset(orig_y, 0, y_plane_size);
  memset(orig_u, 0, uv_plane_size);
  memset(orig_v, 0, uv_plane_size);
  memset(ro0_y, 0, y_plane_size);
  memset(ro0_u, 0, uv_plane_size);
  memset(ro0_v, 0, uv_plane_size);
  memset(ro90_y, 0, y_plane_size);
  memset(ro90_u, 0, uv_plane_size);
  memset(ro90_v, 0, uv_plane_size);
  memset(ro270_y, 0, y_plane_size);
  memset(ro270_u, 0, uv_plane_size);
  memset(ro270_v, 0, uv_plane_size);
833 834 835 836

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
837
      orig_y[i * (yw + b * 2) + j] = random() & 0xff;
838 839 840 841 842
    }
  }

  for (i = b; i < (uvh + b); ++i) {
    for (j = b; j < (uvw + b); ++j) {
843 844
      orig_u[i * (uvw + b * 2) + j] = random() & 0xff;
      orig_v[i * (uvw + b * 2) + j] = random() & 0xff;
845 846 847
    }
  }

848 849 850 851
  int y_off_0 = b * (yw + b * 2) + b;
  int uv_off_0 = b * (uvw + b * 2) + b;
  int y_off_90 = b * (yh + b * 2) + b;
  int uv_off_90 = b * (uvh + b * 2) + b;
852

853 854 855 856
  int y_st_0 = yw + b * 2;
  int uv_st_0 = uvw + b * 2;
  int y_st_90 = yh + b * 2;
  int uv_st_90 = uvh + b * 2;
857

858 859 860 861 862 863
  I420Rotate(orig_y + y_off_0, y_st_0,
             orig_u + uv_off_0, uv_st_0,
             orig_v + uv_off_0, uv_st_0,
             ro270_y + y_off_90, y_st_90,
             ro270_u + uv_off_90, uv_st_90,
             ro270_v + uv_off_90, uv_st_90,
864 865 866
             yw, yh,
             kRotateCounterClockwise);

867 868 869 870 871 872
  I420Rotate(ro270_y + y_off_90, y_st_90,
             ro270_u + uv_off_90, uv_st_90,
             ro270_v + uv_off_90, uv_st_90,
             ro90_y + y_off_90, y_st_90,
             ro90_u + uv_off_90, uv_st_90,
             ro90_v + uv_off_90, uv_st_90,
873 874 875
             yh, yw,
             kRotate180);

876 877 878 879 880 881
  I420Rotate(ro90_y + y_off_90, y_st_90,
             ro90_u + uv_off_90, uv_st_90,
             ro90_v + uv_off_90, uv_st_90,
             ro0_y + y_off_0, y_st_0,
             ro0_u + uv_off_0, uv_st_0,
             ro0_v + uv_off_0, uv_st_0,
882 883 884 885
             yh, yw,
             kRotateCounterClockwise);

  for (i = 0; i < y_plane_size; ++i) {
886
    if (orig_y[i] != ro0_y[i]) {
887
      ++err;
888
    }
889 890 891
  }

  for (i = 0; i < uv_plane_size; ++i) {
892
    if (orig_u[i] != ro0_u[i]) {
893
      ++err;
894 895
    }
    if (orig_v[i] != ro0_v[i]) {
896
      ++err;
897
    }
898 899
  }

900 901 902 903 904 905 906 907 908 909 910 911
  free_aligned_buffer_64(orig_y)
  free_aligned_buffer_64(orig_u)
  free_aligned_buffer_64(orig_v)
  free_aligned_buffer_64(ro0_y)
  free_aligned_buffer_64(ro0_u)
  free_aligned_buffer_64(ro0_v)
  free_aligned_buffer_64(ro90_y)
  free_aligned_buffer_64(ro90_u)
  free_aligned_buffer_64(ro90_v)
  free_aligned_buffer_64(ro270_y)
  free_aligned_buffer_64(ro270_u)
  free_aligned_buffer_64(ro270_v)
912 913 914 915 916 917 918

  EXPECT_EQ(0, err);
}

TEST_F(libyuvTest, NV12ToI420Rotate90) {
  int err = 0;

919 920
  int yw = benchmark_width_;
  int yh = benchmark_height_;
921
  int b = 128;
922 923
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
924 925
  int i, j;

926 927
  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
928
  int nv_uv_plane_size = (uvw * 2 + b * 2) * (uvh + b * 2);
929 930 931

  srandom(time(NULL));

932 933 934 935 936 937 938 939
  align_buffer_64(orig_y, y_plane_size)
  align_buffer_64(orig_uv, nv_uv_plane_size)
  align_buffer_64(ro0_y, y_plane_size)
  align_buffer_64(ro0_u, uv_plane_size)
  align_buffer_64(ro0_v, uv_plane_size)
  align_buffer_64(ro90_y, y_plane_size)
  align_buffer_64(ro90_u, uv_plane_size)
  align_buffer_64(ro90_v, uv_plane_size)
940 941 942 943 944 945 946 947
  memset(orig_y, 0, y_plane_size);
  memset(orig_uv, 0, uv_plane_size);
  memset(ro0_y, 0, y_plane_size);
  memset(ro0_u, 0, uv_plane_size);
  memset(ro0_v, 0, uv_plane_size);
  memset(ro90_y, 0, y_plane_size);
  memset(ro90_u, 0, uv_plane_size);
  memset(ro90_v, 0, uv_plane_size);
948 949 950 951

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
952
      orig_y[i * (yw + b * 2) + j] = random() & 0xff;
953 954 955 956
    }
  }

  for (i = b; i < (uvh + b); ++i) {
957
    for (j = b; j < (uvw * 2 + b); j += 2) {
958
      uint8 random_number = random() & 0x7f;
959 960
      orig_uv[i * (uvw * 2 + b * 2) + j] = random_number;
      orig_uv[i * (uvw * 2 + b * 2) + j + 1] = -random_number;
961 962 963
    }
  }

964 965 966 967
  int y_off_0 = b * (yw + b * 2) + b;
  int uv_off_0 = b * (uvw + b * 2) + b;
  int y_off_90 = b * (yh + b * 2) + b;
  int uv_off_90 = b * (uvh + b * 2) + b;
968

969 970 971 972
  int y_st_0 = yw + b * 2;
  int uv_st_0 = uvw + b * 2;
  int y_st_90 = yh + b * 2;
  int uv_st_90 = uvh + b * 2;
973

974 975 976 977 978
  NV12ToI420Rotate(orig_y + y_off_0, y_st_0,
                   orig_uv + y_off_0, y_st_0,
                   ro90_y + y_off_90, y_st_90,
                   ro90_u + uv_off_90, uv_st_90,
                   ro90_v + uv_off_90, uv_st_90,
979 980 981
                   yw, yh,
                   kRotateClockwise);

982 983 984 985 986 987
  I420Rotate(ro90_y + y_off_90, y_st_90,
             ro90_u + uv_off_90, uv_st_90,
             ro90_v + uv_off_90, uv_st_90,
             ro0_y + y_off_0, y_st_0,
             ro0_u + uv_off_0, uv_st_0,
             ro0_v + uv_off_0, uv_st_0,
988 989 990 991 992 993 994 995 996 997 998
             yh, yw,
             kRotateCounterClockwise);

  for (i = 0; i < y_plane_size; ++i) {
    if (orig_y[i] != ro0_y[i])
      ++err;
  }

  int zero_cnt = 0;

  for (i = 0; i < uv_plane_size; ++i) {
999
    if ((signed char)ro0_u[i] != -(signed char)ro0_v[i]) {
1000
      ++err;
1001 1002
    }
    if (ro0_u[i] != 0) {
1003
      ++zero_cnt;
1004
    }
1005 1006
  }

1007
  if (!zero_cnt) {
1008
    ++err;
1009
  }
1010

1011 1012 1013 1014 1015 1016 1017 1018
  free_aligned_buffer_64(orig_y)
  free_aligned_buffer_64(orig_uv)
  free_aligned_buffer_64(ro0_y)
  free_aligned_buffer_64(ro0_u)
  free_aligned_buffer_64(ro0_v)
  free_aligned_buffer_64(ro90_y)
  free_aligned_buffer_64(ro90_u)
  free_aligned_buffer_64(ro90_v)
1019 1020 1021 1022 1023 1024 1025

  EXPECT_EQ(0, err);
}

TEST_F(libyuvTest, NV12ToI420Rotate270) {
  int err = 0;

1026 1027
  int yw = benchmark_width_;
  int yh = benchmark_height_;
1028
  int b = 128;
1029 1030
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
1031 1032 1033

  int i, j;

1034 1035
  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
1036
  int nv_uv_plane_size = (uvw * 2 + b * 2) * (uvh + b * 2);
1037 1038 1039

  srandom(time(NULL));

1040 1041 1042 1043 1044 1045 1046 1047
  align_buffer_64(orig_y, y_plane_size)
  align_buffer_64(orig_uv, nv_uv_plane_size)
  align_buffer_64(ro0_y, y_plane_size)
  align_buffer_64(ro0_u, uv_plane_size)
  align_buffer_64(ro0_v, uv_plane_size)
  align_buffer_64(ro270_y, y_plane_size)
  align_buffer_64(ro270_u, uv_plane_size)
  align_buffer_64(ro270_v, uv_plane_size)
1048
  memset(orig_y, 0, y_plane_size);
1049
  memset(orig_uv, 0, nv_uv_plane_size);
1050 1051 1052 1053 1054 1055
  memset(ro0_y, 0, y_plane_size);
  memset(ro0_u, 0, uv_plane_size);
  memset(ro0_v, 0, uv_plane_size);
  memset(ro270_y, 0, y_plane_size);
  memset(ro270_u, 0, uv_plane_size);
  memset(ro270_v, 0, uv_plane_size);
1056 1057 1058 1059

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
1060
      orig_y[i * (yw + b * 2) + j] = random() & 0xff;
1061 1062 1063 1064
    }
  }

  for (i = b; i < (uvh + b); ++i) {
1065
    for (j = b; j < (uvw * 2 + b); j += 2) {
1066
      uint8 random_number = random() & 0x7f;
1067 1068
      orig_uv[i * (uvw * 2 + b * 2) + j] = random_number;
      orig_uv[i * (uvw * 2 + b * 2) + j + 1] = -random_number;
1069 1070 1071
    }
  }

1072 1073 1074 1075
  int y_off_0 = b * (yw + b * 2) + b;
  int uv_off_0 = b * (uvw + b * 2) + b;
  int y_off_270 = b * (yh + b * 2) + b;
  int uv_off_270 = b * (uvh + b * 2) + b;
1076

1077 1078 1079 1080
  int y_st_0 = yw + b * 2;
  int uv_st_0 = uvw + b * 2;
  int y_st_270 = yh + b * 2;
  int uv_st_270 = uvh + b * 2;
1081

1082 1083 1084 1085 1086
  NV12ToI420Rotate(orig_y + y_off_0, y_st_0,
                   orig_uv + y_off_0, y_st_0,
                   ro270_y + y_off_270, y_st_270,
                   ro270_u + uv_off_270, uv_st_270,
                   ro270_v + uv_off_270, uv_st_270,
1087 1088 1089
                   yw, yh,
                   kRotateCounterClockwise);

1090 1091 1092 1093 1094 1095
  I420Rotate(ro270_y + y_off_270, y_st_270,
             ro270_u + uv_off_270, uv_st_270,
             ro270_v + uv_off_270, uv_st_270,
             ro0_y + y_off_0, y_st_0,
             ro0_u + uv_off_0, uv_st_0,
             ro0_v + uv_off_0, uv_st_0,
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
             yh, yw,
             kRotateClockwise);

  for (i = 0; i < y_plane_size; ++i) {
    if (orig_y[i] != ro0_y[i])
      ++err;
  }

  int zero_cnt = 0;

  for (i = 0; i < uv_plane_size; ++i) {
1107
    if ((signed char)ro0_u[i] != -(signed char)ro0_v[i]) {
1108
      ++err;
1109 1110
    }
    if (ro0_u[i] != 0) {
1111
      ++zero_cnt;
1112
    }
1113 1114
  }

1115
  if (!zero_cnt) {
1116
    ++err;
1117
  }
1118

1119 1120 1121 1122 1123 1124 1125 1126
  free_aligned_buffer_64(orig_y)
  free_aligned_buffer_64(orig_uv)
  free_aligned_buffer_64(ro0_y)
  free_aligned_buffer_64(ro0_u)
  free_aligned_buffer_64(ro0_v)
  free_aligned_buffer_64(ro270_y)
  free_aligned_buffer_64(ro270_u)
  free_aligned_buffer_64(ro270_v)
1127 1128 1129 1130 1131 1132 1133

  EXPECT_EQ(0, err);
}

TEST_F(libyuvTest, NV12ToI420Rotate180) {
  int err = 0;

1134 1135
  int yw = benchmark_width_;
  int yh = benchmark_height_;
1136
  int b = 128;
1137 1138
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
1139 1140 1141

  int i, j;

1142 1143
  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
1144
  int nv_uv_plane_size = (uvw * 2 + b * 2) * (uvh + b * 2);
1145 1146 1147

  srandom(time(NULL));

1148 1149 1150 1151 1152 1153 1154 1155
  align_buffer_64(orig_y, y_plane_size)
  align_buffer_64(orig_uv, nv_uv_plane_size)
  align_buffer_64(ro0_y, y_plane_size)
  align_buffer_64(ro0_u, uv_plane_size)
  align_buffer_64(ro0_v, uv_plane_size)
  align_buffer_64(ro180_y, y_plane_size)
  align_buffer_64(ro180_u, uv_plane_size)
  align_buffer_64(ro180_v, uv_plane_size)
1156
  memset(orig_y, 0, y_plane_size);
1157
  memset(orig_uv, 0, nv_uv_plane_size);
1158 1159 1160 1161 1162 1163
  memset(ro0_y, 0, y_plane_size);
  memset(ro0_u, 0, uv_plane_size);
  memset(ro0_v, 0, uv_plane_size);
  memset(ro180_y, 0, y_plane_size);
  memset(ro180_u, 0, uv_plane_size);
  memset(ro180_v, 0, uv_plane_size);
1164 1165 1166 1167

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
1168
      orig_y[i * (yw + b * 2) + j] = random() & 0xff;
1169 1170 1171 1172
    }
  }

  for (i = b; i < (uvh + b); ++i) {
1173
    for (j = b; j < (uvw * 2 + b); j += 2) {
1174
      uint8 random_number = random() & 0x7f;
1175 1176
      orig_uv[i * (uvw * 2 + b * 2) + j] = random_number;
      orig_uv[i * (uvw * 2 + b * 2) + j + 1] = -random_number;
1177 1178 1179
    }
  }

1180 1181
  int y_off = b * (yw + b * 2) + b;
  int uv_off = b * (uvw + b * 2) + b;
1182
  // TODO(fbarchard): rename to y_stride.
1183 1184
  int y_st = yw + b * 2;
  int uv_st = uvw + b * 2;
1185

1186 1187 1188 1189 1190
  NV12ToI420Rotate(orig_y + y_off, y_st,
                   orig_uv + y_off, y_st,
                   ro180_y + y_off, y_st,
                   ro180_u + uv_off, uv_st,
                   ro180_v + uv_off, uv_st,
1191 1192 1193
                   yw, yh,
                   kRotate180);

1194 1195 1196 1197 1198 1199
  I420Rotate(ro180_y + y_off, y_st,
             ro180_u + uv_off, uv_st,
             ro180_v + uv_off, uv_st,
             ro0_y + y_off, y_st,
             ro0_u + uv_off, uv_st,
             ro0_v + uv_off, uv_st,
1200 1201 1202 1203
             yw, yh,
             kRotate180);

  for (i = 0; i < y_plane_size; ++i) {
1204
    if (orig_y[i] != ro0_y[i]) {
1205
      ++err;
1206
    }
1207 1208 1209 1210 1211
  }

  int zero_cnt = 0;

  for (i = 0; i < uv_plane_size; ++i) {
1212
    if ((signed char)ro0_u[i] != -(signed char)ro0_v[i]) {
1213
      ++err;
1214 1215
    }
    if (ro0_u[i] != 0) {
1216
      ++zero_cnt;
1217
    }
1218 1219
  }

1220
  if (!zero_cnt) {
1221
    ++err;
1222
  }
1223

1224 1225 1226 1227 1228 1229 1230 1231
  free_aligned_buffer_64(orig_y)
  free_aligned_buffer_64(orig_uv)
  free_aligned_buffer_64(ro0_y)
  free_aligned_buffer_64(ro0_u)
  free_aligned_buffer_64(ro0_v)
  free_aligned_buffer_64(ro180_y)
  free_aligned_buffer_64(ro180_u)
  free_aligned_buffer_64(ro180_v)
1232 1233 1234 1235 1236 1237 1238

  EXPECT_EQ(0, err);
}

TEST_F(libyuvTest, NV12ToI420RotateNegHeight90) {
  int y_err = 0, uv_err = 0;

1239 1240
  int yw = benchmark_width_;
  int yh = benchmark_height_;
1241
  int b = 128;
1242 1243
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
1244 1245
  int i, j;

1246 1247
  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
1248
  int nv_uv_plane_size = (uvw * 2 + b * 2) * (uvh + b * 2);
1249 1250 1251

  srandom(time(NULL));

1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262
  align_buffer_64(orig_y, y_plane_size)
  align_buffer_64(orig_uv, nv_uv_plane_size)
  align_buffer_64(roa_y, y_plane_size)
  align_buffer_64(roa_u, uv_plane_size)
  align_buffer_64(roa_v, uv_plane_size)
  align_buffer_64(rob_y, y_plane_size)
  align_buffer_64(rob_u, uv_plane_size)
  align_buffer_64(rob_v, uv_plane_size)
  align_buffer_64(roc_y, y_plane_size)
  align_buffer_64(roc_u, uv_plane_size)
  align_buffer_64(roc_v, uv_plane_size)
1263
  memset(orig_y, 0, y_plane_size);
1264
  memset(orig_uv, 0, nv_uv_plane_size);
1265 1266 1267 1268 1269 1270 1271 1272 1273
  memset(roa_y, 0, y_plane_size);
  memset(roa_u, 0, uv_plane_size);
  memset(roa_v, 0, uv_plane_size);
  memset(rob_y, 0, y_plane_size);
  memset(rob_u, 0, uv_plane_size);
  memset(rob_v, 0, uv_plane_size);
  memset(roc_y, 0, y_plane_size);
  memset(roc_u, 0, uv_plane_size);
  memset(roc_v, 0, uv_plane_size);
1274 1275 1276 1277

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
1278
      orig_y[i * (yw + b * 2) + j] = random() & 0xff;
1279 1280 1281 1282
    }
  }

  for (i = b; i < (uvh + b); ++i) {
1283
    for (j = b; j < (uvw * 2 + b); j += 2) {
1284
      uint8 random_number = random() & 0x7f;
1285 1286
      orig_uv[i * (uvw * 2 + b * 2) + j] = random_number;
      orig_uv[i * (uvw * 2 + b * 2) + j + 1] = -random_number;
1287 1288 1289
    }
  }

1290 1291 1292 1293
  int y_off_0 = b * (yw + b * 2) + b;
  int uv_off_0 = b * (uvw + b * 2) + b;
  int y_off_90 = b * (yh + b * 2) + b;
  int uv_off_90 = b * (uvh + b * 2) + b;
1294

1295 1296 1297 1298
  int y_st_0 = yw + b * 2;
  int uv_st_0 = uvw + b * 2;
  int y_st_90 = yh + b * 2;
  int uv_st_90 = uvh + b * 2;
1299

1300 1301 1302 1303 1304
  NV12ToI420Rotate(orig_y + y_off_0, y_st_0,
                   orig_uv + y_off_0, y_st_0,
                   roa_y + y_off_90, y_st_90,
                   roa_u + uv_off_90, uv_st_90,
                   roa_v + uv_off_90, uv_st_90,
1305 1306 1307
                   yw, -yh,
                   kRotateClockwise);

1308 1309 1310 1311 1312 1313
  I420Rotate(roa_y + y_off_90, y_st_90,
             roa_u + uv_off_90, uv_st_90,
             roa_v + uv_off_90, uv_st_90,
             rob_y + y_off_0, y_st_0,
             rob_u + uv_off_0, uv_st_0,
             rob_v + uv_off_0, uv_st_0,
1314 1315 1316
             yh, -yw,
             kRotateCounterClockwise);

1317 1318 1319 1320 1321 1322
  I420Rotate(rob_y + y_off_0, y_st_0,
             rob_u + uv_off_0, uv_st_0,
             rob_v + uv_off_0, uv_st_0,
             roc_y + y_off_0, y_st_0,
             roc_u + uv_off_0, uv_st_0,
             roc_v + uv_off_0, uv_st_0,
1323 1324 1325 1326
             yw, yh,
             kRotate180);

  for (i = 0; i < y_plane_size; ++i) {
1327
    if (orig_y[i] != roc_y[i]) {
1328
      ++y_err;
1329
    }
1330 1331 1332 1333
  }

  if (y_err) {
    printf("input %dx%d \n", yw, yh);
1334
    PrintArray(orig_y, y_st_0, yh + b * 2);
1335 1336

    printf("rotate a\n");
1337
    PrintArray(roa_y, y_st_90, y_st_0);
1338 1339

    printf("rotate b\n");
1340
    PrintArray(rob_y, y_st_90, y_st_0);
1341 1342

    printf("rotate c\n");
1343
    PrintArray(roc_y, y_st_0, y_st_90);
1344 1345 1346 1347 1348
  }

  int zero_cnt = 0;

  for (i = 0; i < uv_plane_size; ++i) {
1349
    if ((signed char)roc_u[i] != -(signed char)roc_v[i]) {
1350
      ++uv_err;
1351 1352
    }
    if (rob_u[i] != 0) {
1353
      ++zero_cnt;
1354
    }
1355 1356
  }

1357
  if (!zero_cnt) {
1358
    ++uv_err;
1359
  }
1360 1361

  if (uv_err) {
1362 1363
    printf("input %dx%d \n", uvw * 2, uvh);
    PrintArray(orig_uv, y_st_0, uvh + b * 2);
1364 1365

    printf("rotate a\n");
1366 1367
    PrintArray(roa_u, uv_st_90, uv_st_0);
    PrintArray(roa_v, uv_st_90, uv_st_0);
1368 1369

    printf("rotate b\n");
1370 1371
    PrintArray(rob_u, uv_st_90, uv_st_0);
    PrintArray(rob_v, uv_st_90, uv_st_0);
1372 1373

    printf("rotate c\n");
1374 1375
    PrintArray(roc_u, uv_st_0, uv_st_90);
    PrintArray(roc_v, uv_st_0, uv_st_90);
1376 1377
  }

1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
  free_aligned_buffer_64(orig_y)
  free_aligned_buffer_64(orig_uv)
  free_aligned_buffer_64(roa_y)
  free_aligned_buffer_64(roa_u)
  free_aligned_buffer_64(roa_v)
  free_aligned_buffer_64(rob_y)
  free_aligned_buffer_64(rob_u)
  free_aligned_buffer_64(rob_v)
  free_aligned_buffer_64(roc_y)
  free_aligned_buffer_64(roc_u)
  free_aligned_buffer_64(roc_v)
1389 1390 1391 1392 1393 1394 1395

  EXPECT_EQ(0, y_err + uv_err);
}

TEST_F(libyuvTest, NV12ToI420RotateNegHeight180) {
  int y_err = 0, uv_err = 0;

1396 1397
  int yw = benchmark_width_;
  int yh = benchmark_height_;
1398
  int b = 128;
1399 1400
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
1401 1402
  int i, j;

1403 1404
  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
1405
  int nv_uv_plane_size = (uvw * 2 + b * 2) * (uvh + b * 2);
1406 1407 1408

  srandom(time(NULL));

1409 1410 1411 1412 1413 1414 1415 1416
  align_buffer_64(orig_y, y_plane_size)
  align_buffer_64(orig_uv, nv_uv_plane_size)
  align_buffer_64(roa_y, y_plane_size)
  align_buffer_64(roa_u, uv_plane_size)
  align_buffer_64(roa_v, uv_plane_size)
  align_buffer_64(rob_y, y_plane_size)
  align_buffer_64(rob_u, uv_plane_size)
  align_buffer_64(rob_v, uv_plane_size)
1417
  memset(orig_y, 0, y_plane_size);
1418
  memset(orig_uv, 0, nv_uv_plane_size);
1419 1420 1421 1422 1423 1424
  memset(roa_y, 0, y_plane_size);
  memset(roa_u, 0, uv_plane_size);
  memset(roa_v, 0, uv_plane_size);
  memset(rob_y, 0, y_plane_size);
  memset(rob_u, 0, uv_plane_size);
  memset(rob_v, 0, uv_plane_size);
1425 1426 1427 1428

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
1429
      orig_y[i * (yw + b * 2) + j] = random() & 0xff;
1430 1431 1432 1433
    }
  }

  for (i = b; i < (uvh + b); ++i) {
1434
    for (j = b; j < (uvw * 2 + b); j += 2) {
1435
      uint8 random_number = random() & 0x7f;
1436 1437
      orig_uv[i * (uvw * 2 + b * 2) + j] = random_number;
      orig_uv[i * (uvw * 2 + b * 2) + j + 1] = -random_number;
1438 1439 1440
    }
  }

1441 1442
  int y_off = b * (yw + b * 2) + b;
  int uv_off = b * (uvw + b * 2) + b;
1443

1444 1445
  int y_st = yw + b * 2;
  int uv_st = uvw + b * 2;
1446

1447 1448 1449 1450 1451
  NV12ToI420Rotate(orig_y + y_off, y_st,
                   orig_uv + y_off, y_st,
                   roa_y + y_off, y_st,
                   roa_u + uv_off, uv_st,
                   roa_v + uv_off, uv_st,
1452 1453 1454
                   yw, -yh,
                   kRotate180);

1455 1456 1457 1458 1459 1460
  I420Rotate(roa_y + y_off, y_st,
             roa_u + uv_off, uv_st,
             roa_v + uv_off, uv_st,
             rob_y + y_off, y_st,
             rob_u + uv_off, uv_st,
             rob_v + uv_off, uv_st,
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470
             yw, -yh,
             kRotate180);

  for (i = 0; i < y_plane_size; ++i) {
    if (orig_y[i] != rob_y[i])
      ++y_err;
  }

  if (y_err) {
    printf("input %dx%d \n", yw, yh);
1471
    PrintArray(orig_y, y_st, yh + b * 2);
1472 1473

    printf("rotate a\n");
1474
    PrintArray(roa_y, y_st, yh + b * 2);
1475 1476

    printf("rotate b\n");
1477
    PrintArray(rob_y, y_st, yh + b * 2);
1478 1479 1480 1481 1482
  }

  int zero_cnt = 0;

  for (i = 0; i < uv_plane_size; ++i) {
1483
    if ((signed char)rob_u[i] != -(signed char)rob_v[i]) {
1484
      ++uv_err;
1485 1486
    }
    if (rob_u[i] != 0) {
1487
      ++zero_cnt;
1488
    }
1489 1490
  }

1491
  if (!zero_cnt) {
1492
    ++uv_err;
1493
  }
1494 1495

  if (uv_err) {
1496 1497
    printf("input %dx%d \n", uvw * 2, uvh);
    PrintArray(orig_uv, y_st, uvh + b * 2);
1498 1499

    printf("rotate a\n");
1500 1501
    PrintArray(roa_u, uv_st, uvh + b * 2);
    PrintArray(roa_v, uv_st, uvh + b * 2);
1502 1503

    printf("rotate b\n");
1504 1505
    PrintArray(rob_u, uv_st, uvh + b * 2);
    PrintArray(rob_v, uv_st, uvh + b * 2);
1506 1507
  }

1508 1509 1510 1511 1512 1513 1514 1515
  free_aligned_buffer_64(orig_y)
  free_aligned_buffer_64(orig_uv)
  free_aligned_buffer_64(roa_y)
  free_aligned_buffer_64(roa_u)
  free_aligned_buffer_64(roa_v)
  free_aligned_buffer_64(rob_y)
  free_aligned_buffer_64(rob_u)
  free_aligned_buffer_64(rob_v)
1516 1517 1518

  EXPECT_EQ(0, y_err + uv_err);
}
mikhal@webrtc.org's avatar
mikhal@webrtc.org committed
1519

1520 1521
TEST_F(libyuvTest, NV12ToI420SplitUV) {
  int err = 0;
1522 1523
  int yw = benchmark_width_;
  int yh = benchmark_height_;
1524 1525

  int b = 128;
1526 1527
  int uvw = (yw + 1) / 2;
  int uvh = (yh + 1) / 2;
1528 1529 1530 1531 1532 1533
  int i, j;

  int y_plane_size = (yw + b * 2) * (yh + b * 2);
  int uv_plane_size = (uvw + b * 2) * (uvh + b * 2);
  int nv_uv_plane_size = (uvw * 2 + b * 2) * (uvh + b * 2);

1534 1535 1536 1537 1538 1539 1540 1541
  align_buffer_64(src_y, y_plane_size)
  align_buffer_64(src_uv, nv_uv_plane_size)
  align_buffer_64(dst_y_c, y_plane_size)
  align_buffer_64(dst_u_c, uv_plane_size)
  align_buffer_64(dst_v_c, uv_plane_size)
  align_buffer_64(dst_y_opt, y_plane_size)
  align_buffer_64(dst_u_opt, uv_plane_size)
  align_buffer_64(dst_v_opt, uv_plane_size)
1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601

  memset(src_y, 0, y_plane_size);
  memset(src_uv, 0, nv_uv_plane_size);
  memset(dst_y_c, 0, y_plane_size);
  memset(dst_u_c, 0, uv_plane_size);
  memset(dst_v_c, 0, uv_plane_size);
  memset(dst_y_opt, 0, y_plane_size);
  memset(dst_u_opt, 0, uv_plane_size);
  memset(dst_v_opt, 0, uv_plane_size);

  // fill image buffers with random data
  for (i = b; i < (yh + b); ++i) {
    for (j = b; j < (yw + b); ++j) {
      src_y[i * (yw + b * 2) + j] = j;
    }
  }

  for (i = b; i < (uvh + b); ++i) {
    for (j = b; j < (uvw * 2 + b); j += 2) {
      uint8 num = j & 0x7f;
      src_uv[i * (uvw * 2 + b * 2) + j] = num;
      src_uv[i * (uvw * 2 + b * 2) + j + 1] = num;
    }
  }

  // TODO(fbarchard): Add b to pointers and use stride.
  MaskCpuFlags(0);  // Disable all CPU optimization.
  double c_time = get_time();
  NV12ToI420Rotate(src_y, yw,
                   src_uv, uvw * 2,
                   dst_y_c, yw,
                   dst_u_c, uvw,
                   dst_v_c, uvw,
                   yw, yh,
                   kRotate0);
  c_time = (get_time() - c_time);

  MaskCpuFlags(-1);  // Enable all CPU optimization.
  double opt_time = get_time();
  NV12ToI420Rotate(src_y, yw,
                   src_uv, uvw * 2,
                   dst_y_opt, yw,
                   dst_u_opt, uvw,
                   dst_v_opt, uvw,
                   yw, yh,
                   kRotate0);
  opt_time = (get_time() - opt_time);

  // Report performance of C vs OPT.
  printf("SplitUV %8d us C - %8d us OPT\n",
         static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6));

  for (i = 0; i < uv_plane_size; ++i) {
    if ((dst_u_c[i] != dst_u_opt[i]) || (dst_v_c[i] != dst_v_opt[i])) {
      printf("%d. dst_u_c = 0x%x, dst_u_opt = 0x%x dst_v_c = 0x%x, "
             "dst_v_opt = 0x%x\n", i,
             dst_u_c[i], dst_u_opt[i], dst_v_c[i], dst_v_opt[i]);
      ++err;
    }
  }
1602 1603 1604 1605 1606 1607 1608 1609
  free_aligned_buffer_64(src_y)
  free_aligned_buffer_64(src_uv)
  free_aligned_buffer_64(dst_y_c)
  free_aligned_buffer_64(dst_u_c)
  free_aligned_buffer_64(dst_v_c)
  free_aligned_buffer_64(dst_y_opt)
  free_aligned_buffer_64(dst_u_opt)
  free_aligned_buffer_64(dst_v_opt)
1610 1611 1612

  EXPECT_EQ(0, err);
}
1613

frkoenig@google.com's avatar
frkoenig@google.com committed
1614
}  // namespace libyuv