1 // Copyright 2023 Google LLC
2 // SPDX-License-Identifier: BSD-2-Clause
3
4 #include "avif/avif.h"
5 #include "aviftest_helpers.h"
6 #include "gtest/gtest.h"
7
8 namespace {
9
10 struct InvalidClapPropertyParam {
11 uint32_t width;
12 uint32_t height;
13 avifPixelFormat yuv_format;
14 avifCleanApertureBox clap;
15 };
16
17 constexpr InvalidClapPropertyParam kInvalidClapPropertyTestParams[] = {
18 // Zero or negative denominators.
19 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 0, 132, 1, 0, 1, 0, 1}},
20 {120,
21 160,
22 AVIF_PIXEL_FORMAT_YUV420,
23 {96, static_cast<uint32_t>(-1), 132, 1, 0, 1, 0, 1}},
24 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 0, 0, 1, 0, 1}},
25 {120,
26 160,
27 AVIF_PIXEL_FORMAT_YUV420,
28 {96, 1, 132, static_cast<uint32_t>(-1), 0, 1, 0, 1}},
29 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 1, 0, 0, 0, 1}},
30 {120,
31 160,
32 AVIF_PIXEL_FORMAT_YUV420,
33 {96, 1, 132, 1, 0, static_cast<uint32_t>(-1), 0, 1}},
34 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 1, 0, 1, 0, 0}},
35 {120,
36 160,
37 AVIF_PIXEL_FORMAT_YUV420,
38 {96, 1, 132, 1, 0, 1, 0, static_cast<uint32_t>(-1)}},
39 // Zero or negative clean aperture width or height.
40 {120,
41 160,
42 AVIF_PIXEL_FORMAT_YUV420,
43 {static_cast<uint32_t>(-96), 1, 132, 1, 0, 1, 0, 1}},
44 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {0, 1, 132, 1, 0, 1, 0, 1}},
45 {120,
46 160,
47 AVIF_PIXEL_FORMAT_YUV420,
48 {96, 1, static_cast<uint32_t>(-132), 1, 0, 1, 0, 1}},
49 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 0, 1, 0, 1, 0, 1}},
50 // Clean aperture width or height is not an integer.
51 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 5, 132, 1, 0, 1, 0, 1}},
52 {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 5, 0, 1, 0, 1}},
53 // pcX = 103 + (722 - 1)/2 = 463.5
54 // pcY = -308 + (1024 - 1)/2 = 203.5
55 // leftmost = 463.5 - (385 - 1)/2 = 271.5 (not an integer)
56 // topmost = 203.5 - (330 - 1)/2 = 39
57 {722,
58 1024,
59 AVIF_PIXEL_FORMAT_YUV420,
60 {385, 1, 330, 1, 103, 1, static_cast<uint32_t>(-308), 1}},
61 // pcX = -308 + (1024 - 1)/2 = 203.5
62 // pcY = 103 + (722 - 1)/2 = 463.5
63 // leftmost = 203.5 - (330 - 1)/2 = 39
64 // topmost = 463.5 - (385 - 1)/2 = 271.5 (not an integer)
65 {1024,
66 722,
67 AVIF_PIXEL_FORMAT_YUV420,
68 {330, 1, 385, 1, static_cast<uint32_t>(-308), 1, 103, 1}},
69 // pcX = -1/2 + (99 - 1)/2 = 48.5
70 // pcY = -1/2 + (99 - 1)/2 = 48.5
71 // leftmost = 48.5 - (99 - 1)/2 = -0.5 (not an integer)
72 // topmost = 48.5 - (99 - 1)/2 = -0.5 (not an integer)
73 {99,
74 99,
75 AVIF_PIXEL_FORMAT_YUV420,
76 {99, 1, 99, 1, static_cast<uint32_t>(-1), 2, static_cast<uint32_t>(-1),
77 2}},
78 };
79
80 using InvalidClapPropertyTest =
81 ::testing::TestWithParam<InvalidClapPropertyParam>;
82
83 INSTANTIATE_TEST_SUITE_P(Parameterized, InvalidClapPropertyTest,
84 ::testing::ValuesIn(kInvalidClapPropertyTestParams));
85
86 // Negative tests for the avifCropRectConvertCleanApertureBox() function.
TEST_P(InvalidClapPropertyTest,ValidateClapProperty)87 TEST_P(InvalidClapPropertyTest, ValidateClapProperty) {
88 const InvalidClapPropertyParam& param = GetParam();
89 avifCropRect crop_rect;
90 avifDiagnostics diag;
91 EXPECT_FALSE(avifCropRectConvertCleanApertureBox(&crop_rect, ¶m.clap,
92 param.width, param.height,
93 param.yuv_format, &diag));
94 }
95
96 struct ValidClapPropertyParam {
97 uint32_t width;
98 uint32_t height;
99 avifPixelFormat yuv_format;
100 avifCleanApertureBox clap;
101
102 avifCropRect expected_crop_rect;
103 };
104
105 constexpr ValidClapPropertyParam kValidClapPropertyTestParams[] = {
106 // pcX = 0 + (120 - 1)/2 = 59.5
107 // pcY = 0 + (160 - 1)/2 = 79.5
108 // leftmost = 59.5 - (96 - 1)/2 = 12
109 // topmost = 79.5 - (132 - 1)/2 = 14
110 {120,
111 160,
112 AVIF_PIXEL_FORMAT_YUV420,
113 {96, 1, 132, 1, 0, 1, 0, 1},
114 {12, 14, 96, 132}},
115 // pcX = -30 + (120 - 1)/2 = 29.5
116 // pcY = -40 + (160 - 1)/2 = 39.5
117 // leftmost = 29.5 - (60 - 1)/2 = 0
118 // topmost = 39.5 - (80 - 1)/2 = 0
119 {120,
120 160,
121 AVIF_PIXEL_FORMAT_YUV420,
122 {60, 1, 80, 1, static_cast<uint32_t>(-30), 1, static_cast<uint32_t>(-40),
123 1},
124 {0, 0, 60, 80}},
125 // pcX = -1/2 + (100 - 1)/2 = 49
126 // pcY = -1/2 + (100 - 1)/2 = 49
127 // leftmost = 49 - (99 - 1)/2 = 0
128 // topmost = 49 - (99 - 1)/2 = 0
129 {100,
130 100,
131 AVIF_PIXEL_FORMAT_YUV420,
132 {99, 1, 99, 1, static_cast<uint32_t>(-1), 2, static_cast<uint32_t>(-1), 2},
133 {0, 0, 99, 99}},
134 };
135
136 using ValidClapPropertyTest = ::testing::TestWithParam<ValidClapPropertyParam>;
137
138 INSTANTIATE_TEST_SUITE_P(Parameterized, ValidClapPropertyTest,
139 ::testing::ValuesIn(kValidClapPropertyTestParams));
140
141 // Positive tests for the avifCropRectConvertCleanApertureBox() function.
TEST_P(ValidClapPropertyTest,ValidateClapProperty)142 TEST_P(ValidClapPropertyTest, ValidateClapProperty) {
143 const ValidClapPropertyParam& param = GetParam();
144 avifCropRect crop_rect;
145 avifDiagnostics diag;
146 EXPECT_TRUE(avifCropRectConvertCleanApertureBox(&crop_rect, ¶m.clap,
147 param.width, param.height,
148 param.yuv_format, &diag))
149 << diag.error;
150 EXPECT_EQ(crop_rect.x, param.expected_crop_rect.x);
151 EXPECT_EQ(crop_rect.y, param.expected_crop_rect.y);
152 EXPECT_EQ(crop_rect.width, param.expected_crop_rect.width);
153 EXPECT_EQ(crop_rect.height, param.expected_crop_rect.height);
154 }
155
156 } // namespace
157