Fix cropping of YUV images by amounts that are finer than the U/V resolution (and...
[dcpomatic.git] / test / image_test.cc
1
2 BOOST_AUTO_TEST_CASE (aligned_image_test)
3 {
4         SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), true);
5         BOOST_CHECK_EQUAL (s->components(), 1);
6         /* 160 is 150 aligned to the nearest 32 bytes */
7         BOOST_CHECK_EQUAL (s->stride()[0], 160);
8         BOOST_CHECK_EQUAL (s->line_size()[0], 150);
9         BOOST_CHECK (s->data()[0]);
10         BOOST_CHECK (!s->data()[1]);
11         BOOST_CHECK (!s->data()[2]);
12         BOOST_CHECK (!s->data()[3]);
13
14         /* copy constructor */
15         SimpleImage* t = new SimpleImage (*s);
16         BOOST_CHECK_EQUAL (t->components(), 1);
17         BOOST_CHECK_EQUAL (t->stride()[0], 160);
18         BOOST_CHECK_EQUAL (t->line_size()[0], 150);
19         BOOST_CHECK (t->data()[0]);
20         BOOST_CHECK (!t->data()[1]);
21         BOOST_CHECK (!t->data()[2]);
22         BOOST_CHECK (!t->data()[3]);
23         BOOST_CHECK (t->data() != s->data());
24         BOOST_CHECK (t->data()[0] != s->data()[0]);
25         BOOST_CHECK (t->line_size() != s->line_size());
26         BOOST_CHECK (t->line_size()[0] == s->line_size()[0]);
27         BOOST_CHECK (t->stride() != s->stride());
28         BOOST_CHECK (t->stride()[0] == s->stride()[0]);
29
30         /* assignment operator */
31         SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), false);
32         *u = *s;
33         BOOST_CHECK_EQUAL (u->components(), 1);
34         BOOST_CHECK_EQUAL (u->stride()[0], 160);
35         BOOST_CHECK_EQUAL (u->line_size()[0], 150);
36         BOOST_CHECK (u->data()[0]);
37         BOOST_CHECK (!u->data()[1]);
38         BOOST_CHECK (!u->data()[2]);
39         BOOST_CHECK (!u->data()[3]);
40         BOOST_CHECK (u->data() != s->data());
41         BOOST_CHECK (u->data()[0] != s->data()[0]);
42         BOOST_CHECK (u->line_size() != s->line_size());
43         BOOST_CHECK (u->line_size()[0] == s->line_size()[0]);
44         BOOST_CHECK (u->stride() != s->stride());
45         BOOST_CHECK (u->stride()[0] == s->stride()[0]);
46
47         delete s;
48         delete t;
49         delete u;
50 }
51
52 BOOST_AUTO_TEST_CASE (compact_image_test)
53 {
54         SimpleImage* s = new SimpleImage (PIX_FMT_RGB24, libdcp::Size (50, 50), false);
55         BOOST_CHECK_EQUAL (s->components(), 1);
56         BOOST_CHECK_EQUAL (s->stride()[0], 50 * 3);
57         BOOST_CHECK_EQUAL (s->line_size()[0], 50 * 3);
58         BOOST_CHECK (s->data()[0]);
59         BOOST_CHECK (!s->data()[1]);
60         BOOST_CHECK (!s->data()[2]);
61         BOOST_CHECK (!s->data()[3]);
62
63         /* copy constructor */
64         SimpleImage* t = new SimpleImage (*s);
65         BOOST_CHECK_EQUAL (t->components(), 1);
66         BOOST_CHECK_EQUAL (t->stride()[0], 50 * 3);
67         BOOST_CHECK_EQUAL (t->line_size()[0], 50 * 3);
68         BOOST_CHECK (t->data()[0]);
69         BOOST_CHECK (!t->data()[1]);
70         BOOST_CHECK (!t->data()[2]);
71         BOOST_CHECK (!t->data()[3]);
72         BOOST_CHECK (t->data() != s->data());
73         BOOST_CHECK (t->data()[0] != s->data()[0]);
74         BOOST_CHECK (t->line_size() != s->line_size());
75         BOOST_CHECK (t->line_size()[0] == s->line_size()[0]);
76         BOOST_CHECK (t->stride() != s->stride());
77         BOOST_CHECK (t->stride()[0] == s->stride()[0]);
78
79         /* assignment operator */
80         SimpleImage* u = new SimpleImage (PIX_FMT_YUV422P, libdcp::Size (150, 150), true);
81         *u = *s;
82         BOOST_CHECK_EQUAL (u->components(), 1);
83         BOOST_CHECK_EQUAL (u->stride()[0], 50 * 3);
84         BOOST_CHECK_EQUAL (u->line_size()[0], 50 * 3);
85         BOOST_CHECK (u->data()[0]);
86         BOOST_CHECK (!u->data()[1]);
87         BOOST_CHECK (!u->data()[2]);
88         BOOST_CHECK (!u->data()[3]);
89         BOOST_CHECK (u->data() != s->data());
90         BOOST_CHECK (u->data()[0] != s->data()[0]);
91         BOOST_CHECK (u->line_size() != s->line_size());
92         BOOST_CHECK (u->line_size()[0] == s->line_size()[0]);
93         BOOST_CHECK (u->stride() != s->stride());
94         BOOST_CHECK (u->stride()[0] == s->stride()[0]);
95
96         delete s;
97         delete t;
98         delete u;
99 }
100
101 BOOST_AUTO_TEST_CASE (crop_image_test)
102 {
103         /* This was to check out a bug with valgrind, and is probably not very useful */
104         shared_ptr<SimpleImage> image (new SimpleImage (PIX_FMT_YUV420P, libdcp::Size (16, 16), true));
105         image->make_black ();
106         Crop crop;
107         crop.top = 3;
108         image->crop (crop, false);
109 }
110
111 /* Test cropping of a YUV 4:2:0 image by 1 pixel, which used to fail because
112    the U/V copying was not rounded up to the next sample.
113 */
114 BOOST_AUTO_TEST_CASE (crop_image_test2)
115 {
116         /* Here's a 1998 x 1080 image which is black */
117         shared_ptr<Image> image (new SimpleImage (PIX_FMT_YUV420P, libdcp::Size (1998, 1080), true));
118         image->make_black ();
119
120         /* Crop it by 1 pixel */
121         Crop crop;
122         crop.left = 1;
123         image = image->crop (crop, true);
124
125         /* Convert it back to RGB to make comparison to black easier */
126         image = image->scale_and_convert_to_rgb (image->size(), Scaler::from_id ("bicubic"), true);
127
128         /* Check that its still black after the crop */
129         uint8_t* p = image->data()[0];
130         for (int y = 0; y < image->size().height; ++y) {
131                 uint8_t* q = p;
132                 for (int x = 0; x < image->size().width; ++x) {
133                         BOOST_CHECK_EQUAL (*q++, 0);
134                         BOOST_CHECK_EQUAL (*q++, 0);
135                         BOOST_CHECK_EQUAL (*q++, 0);
136                 }
137                 p += image->stride()[0];
138         }
139 }