1/*
2 *  Copyright (c) 2011 The LibYuv project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "libyuv/rotate.h"
12#include "../source/rotate_priv.h"
13#include "unit_test.h"
14#include <stdlib.h>
15#include <time.h>
16
17using namespace libyuv;
18
19void print_array(uint8 *array, int w, int h) {
20  int i, j;
21
22  for (i = 0; i < h; ++i) {
23    for (j = 0; j < w; ++j)
24      printf("%4d", (signed char)array[(i * w) + j]);
25
26    printf("\n");
27  }
28}
29
30TEST_F(libyuvTest, Transpose) {
31  int iw, ih, ow, oh;
32  int err = 0;
33
34  for (iw = 8; iw < _rotate_max_w && !err; ++iw)
35    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
36      int i;
37      uint8 *input;
38      uint8 *output_1;
39      uint8 *output_2;
40
41      ow = ih;
42      oh = iw;
43
44      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
45      output_1 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
46      output_2 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
47
48      for (i = 0; i < (iw * ih); ++i)
49        input[i] = i;
50
51      TransposePlane(input,    iw, output_1, ow, iw, ih);
52      TransposePlane(output_1, ow, output_2, oh, ow, oh);
53
54      for (i = 0; i < (iw * ih); ++i) {
55        if (input[i] != output_2[i])
56          err++;
57      }
58
59      if (err) {
60        printf("input %dx%d \n", iw, ih);
61        print_array(input, iw, ih);
62
63        printf("transpose 1\n");
64        print_array(output_1, ow, oh);
65
66        printf("transpose 2\n");
67        print_array(output_2, iw, ih);
68      }
69
70      free(input);
71      free(output_1);
72      free(output_2);
73    }
74
75  EXPECT_EQ(0, err);
76}
77
78TEST_F(libyuvTest, TransposeUV) {
79  int iw, ih, ow, oh;
80  int err = 0;
81
82  for (iw = 16; iw < _rotate_max_w && !err; iw += 2)
83    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
84      int i;
85      uint8 *input;
86      uint8 *output_a1, *output_b1;
87      uint8 *output_a2, *output_b2;
88
89      ow = ih;
90      oh = iw >> 1;
91
92      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
93      output_a1 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
94      output_b1 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
95      output_a2 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
96      output_b2 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
97
98      for (i = 0; i < (iw * ih); i += 2) {
99        input[i] = i >> 1;
100        input[i + 1] = -(i >> 1);
101      }
102
103      TransposeUV(input, iw, output_a1, ow, output_b1, ow, iw >> 1, ih);
104
105      TransposePlane(output_a1, ow, output_a2, oh, ow, oh);
106      TransposePlane(output_b1, ow, output_b2, oh, ow, oh);
107
108      for (i = 0; i < (iw * ih); i += 2) {
109        if (input[i] != output_a2[i >> 1])
110          err++;
111        if (input[i + 1] != output_b2[i >> 1])
112          err++;
113      }
114
115      if (err) {
116        printf("input %dx%d \n", iw, ih);
117        print_array(input, iw, ih);
118
119        printf("transpose 1\n");
120        print_array(output_a1, ow, oh);
121        print_array(output_b1, ow, oh);
122
123        printf("transpose 2\n");
124        print_array(output_a2, oh, ow);
125        print_array(output_b2, oh, ow);
126      }
127
128      free(input);
129      free(output_a1);
130      free(output_b1);
131      free(output_a2);
132      free(output_b2);
133    }
134
135  EXPECT_EQ(0, err);
136}
137
138TEST_F(libyuvTest, RotatePlane90) {
139  int iw, ih, ow, oh;
140  int err = 0;
141
142  for (iw = 8; iw < _rotate_max_w && !err; ++iw)
143    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
144      int i;
145      uint8 *input;
146      uint8 *output_0;
147      uint8 *output_90;
148      uint8 *output_180;
149      uint8 *output_270;
150
151      ow = ih;
152      oh = iw;
153
154      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
155      output_0 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
156      output_90 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
157      output_180 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
158      output_270 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
159
160      for (i = 0; i < (iw * ih); ++i)
161        input[i] = i;
162
163      RotatePlane90(input,      iw, output_90,  ow, iw, ih);
164      RotatePlane90(output_90,  ow, output_180, oh, ow, oh);
165      RotatePlane90(output_180, oh, output_270, ow, oh, ow);
166      RotatePlane90(output_270, ow, output_0,   iw, ow, oh);
167
168      for (i = 0; i < (iw * ih); ++i) {
169        if (input[i] != output_0[i])
170          err++;
171      }
172
173      if (err) {
174        printf("input %dx%d \n", iw, ih);
175        print_array(input, iw, ih);
176
177        printf("output 90\n");
178        print_array(output_90, ow, oh);
179
180        printf("output 180\n");
181        print_array(output_180, iw, ih);
182
183        printf("output 270\n");
184        print_array(output_270, ow, oh);
185
186        printf("output 0\n");
187        print_array(output_0, iw, ih);
188      }
189
190      free(input);
191      free(output_0);
192      free(output_90);
193      free(output_180);
194      free(output_270);
195    }
196
197  EXPECT_EQ(0, err);
198}
199
200TEST_F(libyuvTest, RotateUV90) {
201  int iw, ih, ow, oh;
202  int err = 0;
203
204  for (iw = 16; iw < _rotate_max_w && !err; iw += 2)
205    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
206      int i;
207      uint8 *input;
208      uint8 *output_0_u;
209      uint8 *output_0_v;
210      uint8 *output_90_u;
211      uint8 *output_90_v;
212      uint8 *output_180_u;
213      uint8 *output_180_v;
214
215      ow = ih;
216      oh = iw >> 1;
217
218      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
219      output_0_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
220      output_0_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
221      output_90_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
222      output_90_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
223      output_180_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
224      output_180_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
225
226      for (i = 0; i < (iw * ih); i += 2) {
227        input[i] = i >> 1;
228        input[i + 1] = -(i >> 1);
229      }
230
231      RotateUV90(input, iw, output_90_u, ow, output_90_v, ow, iw >> 1, ih);
232
233      RotatePlane90(output_90_u, ow, output_180_u, oh, ow, oh);
234      RotatePlane90(output_90_v, ow, output_180_v, oh, ow, oh);
235
236      RotatePlane180(output_180_u, ow, output_0_u, ow, ow, oh);
237      RotatePlane180(output_180_v, ow, output_0_v, ow, ow, oh);
238
239      for (i = 0; i < (ow * oh); ++i) {
240        if (output_0_u[i] != (uint8)i)
241          err++;
242        if (output_0_v[i] != (uint8)(-i))
243          err++;
244      }
245
246      if (err) {
247        printf("input %dx%d \n", iw, ih);
248        print_array(input, iw, ih);
249
250        printf("output 90_u\n");
251        print_array(output_90_u, ow, oh);
252
253        printf("output 90_v\n");
254        print_array(output_90_v, ow, oh);
255
256        printf("output 180_u\n");
257        print_array(output_180_u, oh, ow);
258
259        printf("output 180_v\n");
260        print_array(output_180_v, oh, ow);
261
262        printf("output 0_u\n");
263        print_array(output_0_u, oh, ow);
264
265        printf("output 0_v\n");
266        print_array(output_0_v, oh, ow);
267      }
268
269      free(input);
270      free(output_0_u);
271      free(output_0_v);
272      free(output_90_u);
273      free(output_90_v);
274      free(output_180_u);
275      free(output_180_v);
276    }
277
278  EXPECT_EQ(0, err);
279}
280
281TEST_F(libyuvTest, RotateUV180) {
282  int iw, ih, ow, oh;
283  int err = 0;
284
285  for (iw = 16; iw < _rotate_max_w && !err; iw += 2)
286    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
287      int i;
288      uint8 *input;
289      uint8 *output_0_u;
290      uint8 *output_0_v;
291      uint8 *output_90_u;
292      uint8 *output_90_v;
293      uint8 *output_180_u;
294      uint8 *output_180_v;
295
296      ow = iw >> 1;
297      oh = ih;
298
299      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
300      output_0_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
301      output_0_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
302      output_90_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
303      output_90_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
304      output_180_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
305      output_180_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
306
307      for (i = 0; i < (iw * ih); i += 2) {
308        input[i] = i >> 1;
309        input[i + 1] = -(i >> 1);
310      }
311
312      RotateUV180(input, iw, output_180_u, ow, output_180_v, ow, iw >> 1, ih);
313
314      RotatePlane90(output_180_u, ow, output_90_u, oh, ow, oh);
315      RotatePlane90(output_180_v, ow, output_90_v, oh, ow, oh);
316
317      RotatePlane90(output_90_u, oh, output_0_u, ow, oh, ow);
318      RotatePlane90(output_90_v, oh, output_0_v, ow, oh, ow);
319
320      for (i = 0; i < (ow * oh); ++i) {
321        if (output_0_u[i] != (uint8)i)
322          err++;
323        if (output_0_v[i] != (uint8)(-i))
324          err++;
325      }
326
327      if (err) {
328        printf("input %dx%d \n", iw, ih);
329        print_array(input, iw, ih);
330
331        printf("output 180_u\n");
332        print_array(output_180_u, oh, ow);
333
334        printf("output 180_v\n");
335        print_array(output_180_v, oh, ow);
336
337        printf("output 90_u\n");
338        print_array(output_90_u, oh, ow);
339
340        printf("output 90_v\n");
341        print_array(output_90_v, oh, ow);
342
343        printf("output 0_u\n");
344        print_array(output_0_u, ow, oh);
345
346        printf("output 0_v\n");
347        print_array(output_0_v, ow, oh);
348      }
349
350      free(input);
351      free(output_0_u);
352      free(output_0_v);
353      free(output_90_u);
354      free(output_90_v);
355      free(output_180_u);
356      free(output_180_v);
357    }
358
359  EXPECT_EQ(0, err);
360}
361
362TEST_F(libyuvTest, RotateUV270) {
363  int iw, ih, ow, oh;
364  int err = 0;
365
366  for (iw = 16; iw < _rotate_max_w && !err; iw += 2)
367    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
368      int i;
369      uint8 *input;
370      uint8 *output_0_u;
371      uint8 *output_0_v;
372      uint8 *output_270_u;
373      uint8 *output_270_v;
374      uint8 *output_180_u;
375      uint8 *output_180_v;
376
377      ow = ih;
378      oh = iw >> 1;
379
380      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
381      output_0_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
382      output_0_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
383      output_270_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
384      output_270_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
385      output_180_u = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
386      output_180_v = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
387
388      for (i = 0; i < (iw * ih); i += 2) {
389        input[i] = i >> 1;
390        input[i + 1] = -(i >> 1);
391      }
392
393      RotateUV270(input, iw, output_270_u, ow, output_270_v, ow,
394                       iw >> 1, ih);
395
396      RotatePlane270(output_270_u, ow, output_180_u, oh, ow, oh);
397      RotatePlane270(output_270_v, ow, output_180_v, oh, ow, oh);
398
399      RotatePlane180(output_180_u, ow, output_0_u, ow, ow, oh);
400      RotatePlane180(output_180_v, ow, output_0_v, ow, ow, oh);
401
402      for (i = 0; i < (ow * oh); ++i) {
403        if (output_0_u[i] != (uint8)i)
404          err++;
405        if (output_0_v[i] != (uint8)(-i))
406          err++;
407      }
408
409      if (err) {
410        printf("input %dx%d \n", iw, ih);
411        print_array(input, iw, ih);
412
413        printf("output 270_u\n");
414        print_array(output_270_u, ow, oh);
415
416        printf("output 270_v\n");
417        print_array(output_270_v, ow, oh);
418
419        printf("output 180_u\n");
420        print_array(output_180_u, oh, ow);
421
422        printf("output 180_v\n");
423        print_array(output_180_v, oh, ow);
424
425        printf("output 0_u\n");
426        print_array(output_0_u, oh, ow);
427
428        printf("output 0_v\n");
429        print_array(output_0_v, oh, ow);
430      }
431
432      free(input);
433      free(output_0_u);
434      free(output_0_v);
435      free(output_270_u);
436      free(output_270_v);
437      free(output_180_u);
438      free(output_180_v);
439    }
440
441  EXPECT_EQ(0, err);
442}
443
444TEST_F(libyuvTest, RotatePlane180) {
445  int iw, ih, ow, oh;
446  int err = 0;
447
448  for (iw = 8; iw < _rotate_max_w && !err; ++iw)
449    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
450      int i;
451      uint8 *input;
452      uint8 *output_0;
453      uint8 *output_180;
454
455      ow = iw;
456      oh = ih;
457
458      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
459      output_0 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
460      output_180 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
461
462      for (i = 0; i < (iw * ih); ++i)
463        input[i] = i;
464
465      RotatePlane180(input,      iw, output_180, ow, iw, ih);
466      RotatePlane180(output_180, ow, output_0,   iw, ow, oh);
467
468      for (i = 0; i < (iw * ih); ++i) {
469        if (input[i] != output_0[i])
470          err++;
471      }
472
473      if (err) {
474        printf("input %dx%d \n", iw, ih);
475        print_array(input, iw, ih);
476
477        printf("output 180\n");
478        print_array(output_180, iw, ih);
479
480        printf("output 0\n");
481        print_array(output_0, iw, ih);
482      }
483
484      free(input);
485      free(output_0);
486      free(output_180);
487    }
488
489  EXPECT_EQ(0, err);
490}
491
492TEST_F(libyuvTest, RotatePlane270) {
493  int iw, ih, ow, oh;
494  int err = 0;
495
496  for (iw = 8; iw < _rotate_max_w && !err; ++iw)
497    for (ih = 8; ih < _rotate_max_h && !err; ++ih) {
498      int i;
499      uint8 *input;
500      uint8 *output_0;
501      uint8 *output_90;
502      uint8 *output_180;
503      uint8 *output_270;
504
505      ow = ih;
506      oh = iw;
507
508      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
509      output_0 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
510      output_90 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
511      output_180 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
512      output_270 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
513
514      for (i = 0; i < (iw * ih); ++i)
515        input[i] = i;
516
517      RotatePlane270(input,      iw, output_270, ow, iw, ih);
518      RotatePlane270(output_270, ow, output_180, oh, ow, oh);
519      RotatePlane270(output_180, oh, output_90,  ow, oh, ow);
520      RotatePlane270(output_90,  ow, output_0,   iw, ow, oh);
521
522      for (i = 0; i < (iw * ih); ++i) {
523        if (input[i] != output_0[i])
524          err++;
525      }
526
527      if (err) {
528        printf("input %dx%d \n", iw, ih);
529        print_array(input, iw, ih);
530
531        printf("output 270\n");
532        print_array(output_270, ow, oh);
533
534        printf("output 180\n");
535        print_array(output_180, iw, ih);
536
537        printf("output 90\n");
538        print_array(output_90, ow, oh);
539
540        printf("output 0\n");
541        print_array(output_0, iw, ih);
542      }
543
544      free(input);
545      free(output_0);
546      free(output_90);
547      free(output_180);
548      free(output_270);
549    }
550
551  EXPECT_EQ(0, err);
552}
553
554TEST_F(libyuvTest, RotatePlane90and270) {
555  int iw, ih, ow, oh;
556  int err = 0;
557
558  for (iw = 16; iw < _rotate_max_w && !err; iw += 4)
559    for (ih = 16; ih < _rotate_max_h && !err; ih += 4) {
560      int i;
561      uint8 *input;
562      uint8 *output_0;
563      uint8 *output_90;
564      ow = ih;
565      oh = iw;
566
567      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
568      output_0 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
569      output_90 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
570
571      for (i = 0; i < (iw * ih); ++i)
572        input[i] = i;
573
574      RotatePlane90(input,      iw, output_90,  ow, iw, ih);
575      RotatePlane270(output_90, ow, output_0,   iw, ow, oh);
576
577      for (i = 0; i < (iw * ih); ++i) {
578        if (input[i] != output_0[i])
579          err++;
580      }
581
582      if (err) {
583        printf("intput %dx%d\n", iw, ih);
584        print_array(input, iw, ih);
585
586        printf("output \n");
587        print_array(output_90, ow, oh);
588
589        printf("output \n");
590        print_array(output_0, iw, ih);
591      }
592
593      free(input);
594      free(output_0);
595      free(output_90);
596    }
597
598  EXPECT_EQ(0, err);
599}
600
601TEST_F(libyuvTest, RotatePlane90Pitch) {
602  int iw, ih;
603  int err = 0;
604
605  for (iw = 16; iw < _rotate_max_w && !err; iw += 4)
606    for (ih = 16; ih < _rotate_max_h && !err; ih += 4) {
607      int i;
608      uint8 *input;
609      uint8 *output_0;
610      uint8 *output_90;
611      int ow = ih;
612      int oh = iw;
613
614      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
615      output_0 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
616      output_90 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
617
618      for (i = 0; i < (iw * ih); ++i)
619        input[i] = i;
620
621      RotatePlane90(input, iw,
622                    output_90 + (ow >> 1), ow,
623                    iw >> 1, ih >> 1);
624      RotatePlane90(input + (iw >> 1), iw,
625                    output_90 + (ow >> 1) + ow * (oh >> 1), ow,
626                    iw >> 1, ih >> 1);
627      RotatePlane90(input + iw * (ih >> 1), iw,
628                    output_90, ow,
629                    iw >> 1, ih >> 1);
630      RotatePlane90(input + (iw >> 1) + iw * (ih >> 1), iw,
631                    output_90 + ow * (oh >> 1), ow,
632                    iw >> 1, ih >> 1);
633
634      RotatePlane270(output_90, ih, output_0,   iw, ow, oh);
635
636      for (i = 0; i < (iw * ih); ++i) {
637        if (input[i] != output_0[i])
638          err++;
639      }
640
641      if (err) {
642        printf("intput %dx%d\n", iw, ih);
643        print_array(input, iw, ih);
644
645        printf("output \n");
646        print_array(output_90, ow, oh);
647
648        printf("output \n");
649        print_array(output_0, iw, ih);
650      }
651
652      free(input);
653      free(output_0);
654      free(output_90);
655    }
656
657  EXPECT_EQ(0, err);
658}
659
660TEST_F(libyuvTest, RotatePlane270Pitch) {
661  int iw, ih, ow, oh;
662  int err = 0;
663
664  for (iw = 16; iw < _rotate_max_w && !err; iw += 4)
665    for (ih = 16; ih < _rotate_max_h && !err; ih += 4) {
666      int i;
667      uint8 *input;
668      uint8 *output_0;
669      uint8 *output_270;
670
671      ow = ih;
672      oh = iw;
673
674      input = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
675      output_0 = static_cast<uint8*>(calloc(iw * ih, sizeof(uint8)));
676      output_270 = static_cast<uint8*>(calloc(ow * oh, sizeof(uint8)));
677
678      for (i = 0; i < (iw * ih); ++i)
679        input[i] = i;
680
681      RotatePlane270(input, iw,
682                     output_270 + ow * (oh >> 1), ow,
683                     iw >> 1, ih >> 1);
684      RotatePlane270(input + (iw >> 1), iw,
685                     output_270, ow,
686                     iw >> 1, ih >> 1);
687      RotatePlane270(input + iw * (ih >> 1), iw,
688                     output_270 + (ow >> 1) + ow * (oh >> 1), ow,
689                     iw >> 1, ih >> 1);
690      RotatePlane270(input + (iw >> 1) + iw * (ih >> 1), iw,
691                     output_270 + (ow >> 1), ow,
692                     iw >> 1, ih >> 1);
693
694      RotatePlane90(output_270, ih, output_0,   iw, ow, oh);
695
696      for (i = 0; i < (iw * ih); ++i) {
697        if (input[i] != output_0[i])
698          err++;
699      }
700
701      if (err) {
702        printf("intput %dx%d\n", iw, ih);
703        print_array(input, iw, ih);
704
705        printf("output \n");
706        print_array(output_270, ow, oh);
707
708        printf("output \n");
709        print_array(output_0, iw, ih);
710      }
711
712      free(input);
713      free(output_0);
714      free(output_270);
715    }
716
717  EXPECT_EQ(0, err);
718}
719
720TEST_F(libyuvTest, I420Rotate90) {
721  int err = 0;
722  uint8 *orig_y, *orig_u, *orig_v;
723  uint8 *ro0_y, *ro0_u, *ro0_v;
724  uint8 *ro90_y, *ro90_u, *ro90_v;
725  uint8 *ro270_y, *ro270_u, *ro270_v;
726
727  int yw = 1024;
728  int yh = 768;
729  int b = 128;
730  int uvw = (yw + 1) >> 1;
731  int uvh = (yh + 1) >> 1;
732
733  int i, j;
734
735  int y_plane_size = (yw + (2 * b)) * (yh + (2 * b));
736  int uv_plane_size = (uvw + (2 * b)) * (uvh + (2 * b));
737
738  srandom(time(NULL));
739
740  orig_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
741  orig_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
742  orig_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
743
744  ro0_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
745  ro0_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
746  ro0_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
747
748  ro90_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
749  ro90_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
750  ro90_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
751
752  ro270_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
753  ro270_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
754  ro270_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
755
756  // fill image buffers with random data
757  for (i = b; i < (yh + b); ++i) {
758    for (j = b; j < (yw + b); ++j) {
759      orig_y[i * (yw + (2 * b)) + j] = random() & 0xff;
760    }
761  }
762
763  for (i = b; i < (uvh + b); ++i) {
764    for (j = b; j < (uvw + b); ++j) {
765      orig_u[i * (uvw + (2 * b)) + j] = random() & 0xff;
766      orig_v[i * (uvw + (2 * b)) + j] = random() & 0xff;
767    }
768  }
769
770  int y_off_0 = b * (yw + (2 * b)) + b;
771  int uv_off_0 = b * (uvw + (2 * b)) + b;
772  int y_off_90 = b * (yh + (2 * b)) + b;
773  int uv_off_90 = b * (uvh + (2 * b)) + b;
774
775  int y_st_0 = yw + (2 * b);
776  int uv_st_0 = uvw + (2 * b);
777  int y_st_90 = yh + (2 * b);
778  int uv_st_90 = uvh + (2 * b);
779
780  I420Rotate(orig_y+y_off_0, y_st_0,
781             orig_u+uv_off_0, uv_st_0,
782             orig_v+uv_off_0, uv_st_0,
783             ro90_y+y_off_90, y_st_90,
784             ro90_u+uv_off_90, uv_st_90,
785             ro90_v+uv_off_90, uv_st_90,
786             yw, yh,
787             kRotateClockwise);
788
789  I420Rotate(ro90_y+y_off_90, y_st_90,
790             ro90_u+uv_off_90, uv_st_90,
791             ro90_v+uv_off_90, uv_st_90,
792             ro270_y+y_off_90, y_st_90,
793             ro270_u+uv_off_90, uv_st_90,
794             ro270_v+uv_off_90, uv_st_90,
795             yh, yw,
796             kRotate180);
797
798  I420Rotate(ro270_y+y_off_90, y_st_90,
799             ro270_u+uv_off_90, uv_st_90,
800             ro270_v+uv_off_90, uv_st_90,
801             ro0_y+y_off_0, y_st_0,
802             ro0_u+uv_off_0, uv_st_0,
803             ro0_v+uv_off_0, uv_st_0,
804             yh, yw,
805             kRotateClockwise);
806
807  for (i = 0; i < y_plane_size; ++i) {
808    if (orig_y[i] != ro0_y[i])
809      ++err;
810  }
811
812  for (i = 0; i < uv_plane_size; ++i) {
813    if (orig_u[i] != ro0_u[i])
814      ++err;
815    if (orig_v[i] != ro0_v[i])
816      ++err;
817  }
818
819  free(orig_y);
820  free(orig_u);
821  free(orig_v);
822  free(ro0_y);
823  free(ro0_u);
824  free(ro0_v);
825  free(ro90_y);
826  free(ro90_u);
827  free(ro90_v);
828  free(ro270_y);
829  free(ro270_u);
830  free(ro270_v);
831
832  EXPECT_EQ(0, err);
833}
834
835TEST_F(libyuvTest, I420Rotate270) {
836  int err = 0;
837  uint8 *orig_y, *orig_u, *orig_v;
838  uint8 *ro0_y, *ro0_u, *ro0_v;
839  uint8 *ro90_y, *ro90_u, *ro90_v;
840  uint8 *ro270_y, *ro270_u, *ro270_v;
841
842  int yw = 1024;
843  int yh = 768;
844  int b = 128;
845  int uvw = (yw + 1) >> 1;
846  int uvh = (yh + 1) >> 1;
847
848  int i, j;
849
850  int y_plane_size = (yw + (2 * b)) * (yh + (2 * b));
851  int uv_plane_size = (uvw + (2 * b)) * (uvh + (2 * b));
852
853  srandom(time(NULL));
854
855  orig_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
856  orig_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
857  orig_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
858
859  ro0_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
860  ro0_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
861  ro0_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
862
863  ro90_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
864  ro90_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
865  ro90_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
866
867  ro270_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
868  ro270_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
869  ro270_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
870
871  // fill image buffers with random data
872  for (i = b; i < (yh + b); ++i) {
873    for (j = b; j < (yw + b); ++j) {
874      orig_y[i * (yw + (2 * b)) + j] = random() & 0xff;
875    }
876  }
877
878  for (i = b; i < (uvh + b); ++i) {
879    for (j = b; j < (uvw + b); ++j) {
880      orig_u[i * (uvw + (2 * b)) + j] = random() & 0xff;
881      orig_v[i * (uvw + (2 * b)) + j] = random() & 0xff;
882    }
883  }
884
885  int y_off_0 = b * (yw + (2 * b)) + b;
886  int uv_off_0 = b * (uvw + (2 * b)) + b;
887  int y_off_90 = b * (yh + (2 * b)) + b;
888  int uv_off_90 = b * (uvh + (2 * b)) + b;
889
890  int y_st_0 = yw + (2 * b);
891  int uv_st_0 = uvw + (2 * b);
892  int y_st_90 = yh + (2 * b);
893  int uv_st_90 = uvh + (2 * b);
894
895  I420Rotate(orig_y+y_off_0, y_st_0,
896             orig_u+uv_off_0, uv_st_0,
897             orig_v+uv_off_0, uv_st_0,
898             ro270_y+y_off_90, y_st_90,
899             ro270_u+uv_off_90, uv_st_90,
900             ro270_v+uv_off_90, uv_st_90,
901             yw, yh,
902             kRotateCounterClockwise);
903
904  I420Rotate(ro270_y+y_off_90, y_st_90,
905             ro270_u+uv_off_90, uv_st_90,
906             ro270_v+uv_off_90, uv_st_90,
907             ro90_y+y_off_90, y_st_90,
908             ro90_u+uv_off_90, uv_st_90,
909             ro90_v+uv_off_90, uv_st_90,
910             yh, yw,
911             kRotate180);
912
913  I420Rotate(ro90_y+y_off_90, y_st_90,
914             ro90_u+uv_off_90, uv_st_90,
915             ro90_v+uv_off_90, uv_st_90,
916             ro0_y+y_off_0, y_st_0,
917             ro0_u+uv_off_0, uv_st_0,
918             ro0_v+uv_off_0, uv_st_0,
919             yh, yw,
920             kRotateCounterClockwise);
921
922  for (i = 0; i < y_plane_size; ++i) {
923    if (orig_y[i] != ro0_y[i])
924      ++err;
925  }
926
927  for (i = 0; i < uv_plane_size; ++i) {
928    if (orig_u[i] != ro0_u[i])
929      ++err;
930    if (orig_v[i] != ro0_v[i])
931      ++err;
932  }
933
934  free(orig_y);
935  free(orig_u);
936  free(orig_v);
937  free(ro0_y);
938  free(ro0_u);
939  free(ro0_v);
940  free(ro90_y);
941  free(ro90_u);
942  free(ro90_v);
943  free(ro270_y);
944  free(ro270_u);
945  free(ro270_v);
946
947  EXPECT_EQ(0, err);
948}
949
950TEST_F(libyuvTest, NV12ToI420Rotate90) {
951  int err = 0;
952  uint8 *orig_y, *orig_uv;
953  uint8 *ro0_y, *ro0_u, *ro0_v;
954  uint8 *ro90_y, *ro90_u, *ro90_v;
955
956  int yw = 1024;
957  int yh = 768;
958  int b = 128;
959  int uvw = (yw + 1) >> 1;
960  int uvh = (yh + 1) >> 1;
961  int i, j;
962
963  int y_plane_size = (yw + (2 * b)) * (yh + (2 * b));
964  int uv_plane_size = (uvw + (2 * b)) * (uvh + (2 * b));
965  int o_uv_plane_size = ((2 * uvw) + (2 * b)) * (uvh + (2 * b));
966
967  srandom(time(NULL));
968
969  orig_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
970  orig_uv = static_cast<uint8*>(calloc(o_uv_plane_size, sizeof(uint8)));
971
972  ro0_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
973  ro0_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
974  ro0_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
975
976  ro90_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
977  ro90_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
978  ro90_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
979
980  // fill image buffers with random data
981  for (i = b; i < (yh + b); ++i) {
982    for (j = b; j < (yw + b); ++j) {
983      orig_y[i * (yw + (2 * b)) + j] = random() & 0xff;
984    }
985  }
986
987  for (i = b; i < (uvh + b); ++i) {
988    for (j = b; j < ((2 * uvw) + b); j += 2) {
989      uint8 random_number = random() & 0x7f;
990      orig_uv[i * ((2 * uvw) + (2 * b)) + j] = random_number;
991      orig_uv[i * ((2 * uvw) + (2 * b)) + j + 1] = -random_number;
992    }
993  }
994
995  int y_off_0 = b * (yw + (2 * b)) + b;
996  int uv_off_0 = b * (uvw + (2 * b)) + b;
997  int y_off_90 = b * (yh + (2 * b)) + b;
998  int uv_off_90 = b * (uvh + (2 * b)) + b;
999
1000  int y_st_0 = yw + (2 * b);
1001  int uv_st_0 = uvw + (2 * b);
1002  int y_st_90 = yh + (2 * b);
1003  int uv_st_90 = uvh + (2 * b);
1004
1005  NV12ToI420Rotate(orig_y+y_off_0, y_st_0,
1006                   orig_uv+y_off_0, y_st_0,
1007                   ro90_y+y_off_90, y_st_90,
1008                   ro90_u+uv_off_90, uv_st_90,
1009                   ro90_v+uv_off_90, uv_st_90,
1010                   yw, yh,
1011                   kRotateClockwise);
1012
1013  I420Rotate(ro90_y+y_off_90, y_st_90,
1014             ro90_u+uv_off_90, uv_st_90,
1015             ro90_v+uv_off_90, uv_st_90,
1016             ro0_y+y_off_0, y_st_0,
1017             ro0_u+uv_off_0, uv_st_0,
1018             ro0_v+uv_off_0, uv_st_0,
1019             yh, yw,
1020             kRotateCounterClockwise);
1021
1022  for (i = 0; i < y_plane_size; ++i) {
1023    if (orig_y[i] != ro0_y[i])
1024      ++err;
1025  }
1026
1027  int zero_cnt = 0;
1028
1029  for (i = 0; i < uv_plane_size; ++i) {
1030    if ((signed char)ro0_u[i] != -(signed char)ro0_v[i])
1031      ++err;
1032    if (ro0_u[i] != 0)
1033      ++zero_cnt;
1034  }
1035
1036  if (!zero_cnt)
1037    ++err;
1038
1039  free(orig_y);
1040  free(orig_uv);
1041  free(ro0_y);
1042  free(ro0_u);
1043  free(ro0_v);
1044  free(ro90_y);
1045  free(ro90_u);
1046  free(ro90_v);
1047
1048  EXPECT_EQ(0, err);
1049}
1050
1051TEST_F(libyuvTest, NV12ToI420Rotate270) {
1052  int err = 0;
1053  uint8 *orig_y, *orig_uv;
1054  uint8 *ro0_y, *ro0_u, *ro0_v;
1055  uint8 *ro270_y, *ro270_u, *ro270_v;
1056
1057  int yw = 1024;
1058  int yh = 768;
1059  int b = 128;
1060  int uvw = (yw + 1) >> 1;
1061  int uvh = (yh + 1) >> 1;
1062
1063  int i, j;
1064
1065  int y_plane_size = (yw + (2 * b)) * (yh + (2 * b));
1066  int uv_plane_size = (uvw + (2 * b)) * (uvh + (2 * b));
1067  int o_uv_plane_size = ((2 * uvw) + (2 * b)) * (uvh + (2 * b));
1068
1069  srandom(time(NULL));
1070
1071  orig_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1072  orig_uv = static_cast<uint8*>(calloc(o_uv_plane_size, sizeof(uint8)));
1073
1074  ro0_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1075  ro0_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1076  ro0_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1077
1078  ro270_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1079  ro270_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1080  ro270_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1081
1082  // fill image buffers with random data
1083  for (i = b; i < (yh + b); ++i) {
1084    for (j = b; j < (yw + b); ++j) {
1085      orig_y[i * (yw + (2 * b)) + j] = random() & 0xff;
1086    }
1087  }
1088
1089  for (i = b; i < (uvh + b); ++i) {
1090    for (j = b; j < ((2 * uvw) + b); j += 2) {
1091      uint8 random_number = random() & 0x7f;
1092      orig_uv[i * ((2 * uvw) + (2 * b)) + j] = random_number;
1093      orig_uv[i * ((2 * uvw) + (2 * b)) + j + 1] = -random_number;
1094    }
1095  }
1096
1097  int y_off_0 = b * (yw + (2 * b)) + b;
1098  int uv_off_0 = b * (uvw + (2 * b)) + b;
1099  int y_off_270 = b * (yh + (2 * b)) + b;
1100  int uv_off_270 = b * (uvh + (2 * b)) + b;
1101
1102  int y_st_0 = yw + (2 * b);
1103  int uv_st_0 = uvw + (2 * b);
1104  int y_st_270 = yh + (2 * b);
1105  int uv_st_270 = uvh + (2 * b);
1106
1107  NV12ToI420Rotate(orig_y+y_off_0, y_st_0,
1108                   orig_uv+y_off_0, y_st_0,
1109                   ro270_y+y_off_270, y_st_270,
1110                   ro270_u+uv_off_270, uv_st_270,
1111                   ro270_v+uv_off_270, uv_st_270,
1112                   yw, yh,
1113                   kRotateCounterClockwise);
1114
1115  I420Rotate(ro270_y+y_off_270, y_st_270,
1116             ro270_u+uv_off_270, uv_st_270,
1117             ro270_v+uv_off_270, uv_st_270,
1118             ro0_y+y_off_0, y_st_0,
1119             ro0_u+uv_off_0, uv_st_0,
1120             ro0_v+uv_off_0, uv_st_0,
1121             yh, yw,
1122             kRotateClockwise);
1123
1124  for (i = 0; i < y_plane_size; ++i) {
1125    if (orig_y[i] != ro0_y[i])
1126      ++err;
1127  }
1128
1129  int zero_cnt = 0;
1130
1131  for (i = 0; i < uv_plane_size; ++i) {
1132    if ((signed char)ro0_u[i] != -(signed char)ro0_v[i])
1133      ++err;
1134    if (ro0_u[i] != 0)
1135      ++zero_cnt;
1136  }
1137
1138  if (!zero_cnt)
1139    ++err;
1140
1141  free(orig_y);
1142  free(orig_uv);
1143  free(ro0_y);
1144  free(ro0_u);
1145  free(ro0_v);
1146  free(ro270_y);
1147  free(ro270_u);
1148  free(ro270_v);
1149
1150  EXPECT_EQ(0, err);
1151}
1152
1153TEST_F(libyuvTest, NV12ToI420Rotate180) {
1154  int err = 0;
1155  uint8 *orig_y, *orig_uv;
1156  uint8 *ro0_y, *ro0_u, *ro0_v;
1157  uint8 *ro180_y, *ro180_u, *ro180_v;
1158
1159  int yw = 1024;
1160  int yh = 768;
1161  int b = 128;
1162  int uvw = (yw + 1) >> 1;
1163  int uvh = (yh + 1) >> 1;
1164
1165  int i, j;
1166
1167  int y_plane_size = (yw + (2 * b)) * (yh + (2 * b));
1168  int uv_plane_size = (uvw + (2 * b)) * (uvh + (2 * b));
1169  int o_uv_plane_size = ((2 * uvw) + (2 * b)) * (uvh + (2 * b));
1170
1171  srandom(time(NULL));
1172
1173  orig_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1174  orig_uv = static_cast<uint8*>(calloc(o_uv_plane_size, sizeof(uint8)));
1175
1176  ro0_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1177  ro0_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1178  ro0_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1179
1180  ro180_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1181  ro180_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1182  ro180_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1183
1184  // fill image buffers with random data
1185  for (i = b; i < (yh + b); ++i) {
1186    for (j = b; j < (yw + b); ++j) {
1187      orig_y[i * (yw + (2 * b)) + j] = random() & 0xff;
1188    }
1189  }
1190
1191  for (i = b; i < (uvh + b); ++i) {
1192    for (j = b; j < ((2 * uvw) + b); j += 2) {
1193      uint8 random_number = random() & 0x7f;
1194      orig_uv[i * ((2 * uvw) + (2 * b)) + j] = random_number;
1195      orig_uv[i * ((2 * uvw) + (2 * b)) + j + 1] = -random_number;
1196    }
1197  }
1198
1199  int y_off = b * (yw + (2 * b)) + b;
1200  int uv_off = b * (uvw + (2 * b)) + b;
1201
1202  int y_st = yw + (2 * b);
1203  int uv_st = uvw + (2 * b);
1204
1205  NV12ToI420Rotate(orig_y+y_off, y_st,
1206                   orig_uv+y_off, y_st,
1207                   ro180_y+y_off, y_st,
1208                   ro180_u+uv_off, uv_st,
1209                   ro180_v+uv_off, uv_st,
1210                   yw, yh,
1211                   kRotate180);
1212
1213  I420Rotate(ro180_y+y_off, y_st,
1214             ro180_u+uv_off, uv_st,
1215             ro180_v+uv_off, uv_st,
1216             ro0_y+y_off, y_st,
1217             ro0_u+uv_off, uv_st,
1218             ro0_v+uv_off, uv_st,
1219             yw, yh,
1220             kRotate180);
1221
1222  for (i = 0; i < y_plane_size; ++i) {
1223    if (orig_y[i] != ro0_y[i])
1224      ++err;
1225  }
1226
1227  int zero_cnt = 0;
1228
1229  for (i = 0; i < uv_plane_size; ++i) {
1230    if ((signed char)ro0_u[i] != -(signed char)ro0_v[i])
1231      ++err;
1232    if (ro0_u[i] != 0)
1233      ++zero_cnt;
1234  }
1235
1236  if (!zero_cnt)
1237    ++err;
1238
1239  free(orig_y);
1240  free(orig_uv);
1241  free(ro0_y);
1242  free(ro0_u);
1243  free(ro0_v);
1244  free(ro180_y);
1245  free(ro180_u);
1246  free(ro180_v);
1247
1248  EXPECT_EQ(0, err);
1249}
1250
1251TEST_F(libyuvTest, NV12ToI420RotateNegHeight90) {
1252  int y_err = 0, uv_err = 0;
1253  uint8 *orig_y, *orig_uv;
1254  uint8 *roa_y, *roa_u, *roa_v;
1255  uint8 *rob_y, *rob_u, *rob_v;
1256  uint8 *roc_y, *roc_u, *roc_v;
1257
1258  int yw = 1024;
1259  int yh = 768;
1260  int b = 128;
1261  int uvw = (yw + 1) >> 1;
1262  int uvh = (yh + 1) >> 1;
1263  int i, j;
1264
1265  int y_plane_size = (yw + (2 * b)) * (yh + (2 * b));
1266  int uv_plane_size = (uvw + (2 * b)) * (uvh + (2 * b));
1267  int o_uv_plane_size = ((2 * uvw) + (2 * b)) * (uvh + (2 * b));
1268
1269  srandom(time(NULL));
1270
1271  orig_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1272  orig_uv = static_cast<uint8*>(calloc(o_uv_plane_size, sizeof(uint8)));
1273
1274  roa_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1275  roa_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1276  roa_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1277
1278  rob_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1279  rob_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1280  rob_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1281
1282  roc_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1283  roc_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1284  roc_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1285
1286  // fill image buffers with random data
1287  for (i = b; i < (yh + b); ++i) {
1288    for (j = b; j < (yw + b); ++j) {
1289      orig_y[i * (yw + (2 * b)) + j] = random() & 0xff;
1290    }
1291  }
1292
1293  for (i = b; i < (uvh + b); ++i) {
1294    for (j = b; j < ((2 * uvw) + b); j += 2) {
1295      uint8 random_number = random() & 0x7f;
1296      orig_uv[i * ((2 * uvw) + (2 * b)) + j] = random_number;
1297      orig_uv[i * ((2 * uvw) + (2 * b)) + j + 1] = -random_number;
1298    }
1299  }
1300
1301  int y_off_0 = b * (yw + (2 * b)) + b;
1302  int uv_off_0 = b * (uvw + (2 * b)) + b;
1303  int y_off_90 = b * (yh + (2 * b)) + b;
1304  int uv_off_90 = b * (uvh + (2 * b)) + b;
1305
1306  int y_st_0 = yw + (2 * b);
1307  int uv_st_0 = uvw + (2 * b);
1308  int y_st_90 = yh + (2 * b);
1309  int uv_st_90 = uvh + (2 * b);
1310
1311  NV12ToI420Rotate(orig_y+y_off_0, y_st_0,
1312                   orig_uv+y_off_0, y_st_0,
1313                   roa_y+y_off_90, y_st_90,
1314                   roa_u+uv_off_90, uv_st_90,
1315                   roa_v+uv_off_90, uv_st_90,
1316                   yw, -yh,
1317                   kRotateClockwise);
1318
1319  I420Rotate(roa_y+y_off_90, y_st_90,
1320             roa_u+uv_off_90, uv_st_90,
1321             roa_v+uv_off_90, uv_st_90,
1322             rob_y+y_off_0, y_st_0,
1323             rob_u+uv_off_0, uv_st_0,
1324             rob_v+uv_off_0, uv_st_0,
1325             yh, -yw,
1326             kRotateCounterClockwise);
1327
1328  I420Rotate(rob_y+y_off_0, y_st_0,
1329             rob_u+uv_off_0, uv_st_0,
1330             rob_v+uv_off_0, uv_st_0,
1331             roc_y+y_off_0, y_st_0,
1332             roc_u+uv_off_0, uv_st_0,
1333             roc_v+uv_off_0, uv_st_0,
1334             yw, yh,
1335             kRotate180);
1336
1337  for (i = 0; i < y_plane_size; ++i) {
1338    if (orig_y[i] != roc_y[i])
1339      ++y_err;
1340  }
1341
1342  if (y_err) {
1343    printf("input %dx%d \n", yw, yh);
1344    print_array(orig_y, y_st_0, yh + (2 * b));
1345
1346    printf("rotate a\n");
1347    print_array(roa_y, y_st_90, y_st_0);
1348
1349    printf("rotate b\n");
1350    print_array(rob_y, y_st_90, y_st_0);
1351
1352    printf("rotate c\n");
1353    print_array(roc_y, y_st_0, y_st_90);
1354  }
1355
1356  int zero_cnt = 0;
1357
1358  for (i = 0; i < uv_plane_size; ++i) {
1359    if ((signed char)roc_u[i] != -(signed char)roc_v[i])
1360      ++uv_err;
1361    if (rob_u[i] != 0)
1362      ++zero_cnt;
1363  }
1364
1365  if (!zero_cnt)
1366    ++uv_err;
1367
1368  if (uv_err) {
1369    printf("input %dx%d \n", (2 * uvw), uvh);
1370    print_array(orig_uv, y_st_0, uvh + (2 * b));
1371
1372    printf("rotate a\n");
1373    print_array(roa_u, uv_st_90, uv_st_0);
1374    print_array(roa_v, uv_st_90, uv_st_0);
1375
1376    printf("rotate b\n");
1377    print_array(rob_u, uv_st_90, uv_st_0);
1378    print_array(rob_v, uv_st_90, uv_st_0);
1379
1380    printf("rotate c\n");
1381    print_array(roc_u, uv_st_0, uv_st_90);
1382    print_array(roc_v, uv_st_0, uv_st_90);
1383  }
1384
1385  free(orig_y);
1386  free(orig_uv);
1387  free(roa_y);
1388  free(roa_u);
1389  free(roa_v);
1390  free(rob_y);
1391  free(rob_u);
1392  free(rob_v);
1393  free(roc_y);
1394  free(roc_u);
1395  free(roc_v);
1396
1397  EXPECT_EQ(0, y_err + uv_err);
1398}
1399
1400TEST_F(libyuvTest, NV12ToI420RotateNegHeight180) {
1401  int y_err = 0, uv_err = 0;
1402  uint8 *orig_y, *orig_uv;
1403  uint8 *roa_y, *roa_u, *roa_v;
1404  uint8 *rob_y, *rob_u, *rob_v;
1405
1406  int yw = 1024;
1407  int yh = 768;
1408  int b = 128;
1409  int uvw = (yw + 1) >> 1;
1410  int uvh = (yh + 1) >> 1;
1411  int i, j;
1412
1413  int y_plane_size = (yw + (2 * b)) * (yh + (2 * b));
1414  int uv_plane_size = (uvw + (2 * b)) * (uvh + (2 * b));
1415  int o_uv_plane_size = ((2 * uvw) + (2 * b)) * (uvh + (2 * b));
1416
1417  srandom(time(NULL));
1418
1419  orig_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1420  orig_uv = static_cast<uint8*>(calloc(o_uv_plane_size, sizeof(uint8)));
1421
1422  roa_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1423  roa_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1424  roa_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1425
1426  rob_y = static_cast<uint8*>(calloc(y_plane_size, sizeof(uint8)));
1427  rob_u = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1428  rob_v = static_cast<uint8*>(calloc(uv_plane_size, sizeof(uint8)));
1429
1430  // fill image buffers with random data
1431  for (i = b; i < (yh + b); ++i) {
1432    for (j = b; j < (yw + b); ++j) {
1433      orig_y[i * (yw + (2 * b)) + j] = random() & 0xff;
1434    }
1435  }
1436
1437  for (i = b; i < (uvh + b); ++i) {
1438    for (j = b; j < ((2 * uvw) + b); j += 2) {
1439      uint8 random_number = random() & 0x7f;
1440      orig_uv[i * ((2 * uvw) + (2 * b)) + j] = random_number;
1441      orig_uv[i * ((2 * uvw) + (2 * b)) + j + 1] = -random_number;
1442    }
1443  }
1444
1445  int y_off = b * (yw + (2 * b)) + b;
1446  int uv_off = b * (uvw + (2 * b)) + b;
1447
1448  int y_st = yw + (2 * b);
1449  int uv_st = uvw + (2 * b);
1450
1451  NV12ToI420Rotate(orig_y+y_off, y_st,
1452                   orig_uv+y_off, y_st,
1453                   roa_y+y_off, y_st,
1454                   roa_u+uv_off, uv_st,
1455                   roa_v+uv_off, uv_st,
1456                   yw, -yh,
1457                   kRotate180);
1458
1459  I420Rotate(roa_y+y_off, y_st,
1460             roa_u+uv_off, uv_st,
1461             roa_v+uv_off, uv_st,
1462             rob_y+y_off, y_st,
1463             rob_u+uv_off, uv_st,
1464             rob_v+uv_off, uv_st,
1465             yw, -yh,
1466             kRotate180);
1467
1468  for (i = 0; i < y_plane_size; ++i) {
1469    if (orig_y[i] != rob_y[i])
1470      ++y_err;
1471  }
1472
1473  if (y_err) {
1474    printf("input %dx%d \n", yw, yh);
1475    print_array(orig_y, y_st, yh + (2 * b));
1476
1477    printf("rotate a\n");
1478    print_array(roa_y, y_st, yh + (2 * b));
1479
1480    printf("rotate b\n");
1481    print_array(rob_y, y_st, yh + (2 * b));
1482  }
1483
1484  int zero_cnt = 0;
1485
1486  for (i = 0; i < uv_plane_size; ++i) {
1487    if ((signed char)rob_u[i] != -(signed char)rob_v[i])
1488      ++uv_err;
1489    if (rob_u[i] != 0)
1490      ++zero_cnt;
1491  }
1492
1493  if (!zero_cnt)
1494    ++uv_err;
1495
1496  if (uv_err) {
1497    printf("input %dx%d \n", (2 * uvw), uvh);
1498    print_array(orig_uv, y_st, uvh + (2 * b));
1499
1500    printf("rotate a\n");
1501    print_array(roa_u, uv_st, uvh + (2 * b));
1502    print_array(roa_v, uv_st, uvh + (2 * b));
1503
1504    printf("rotate b\n");
1505    print_array(rob_u, uv_st, uvh + (2 * b));
1506    print_array(rob_v, uv_st, uvh + (2 * b));
1507  }
1508
1509  free(orig_y);
1510  free(orig_uv);
1511  free(roa_y);
1512  free(roa_u);
1513  free(roa_v);
1514  free(rob_y);
1515  free(rob_u);
1516  free(rob_v);
1517
1518  EXPECT_EQ(0, y_err + uv_err);
1519}
1520