/src/libavif/tests/gtest/avif_fuzztest_helpers.h
Line | Count | Source |
1 | | // Copyright 2022 Google LLC |
2 | | // SPDX-License-Identifier: BSD-2-Clause |
3 | | |
4 | | #ifndef LIBAVIF_TESTS_OSS_FUZZ_AVIF_FUZZTEST_HELPERS_H_ |
5 | | #define LIBAVIF_TESTS_OSS_FUZZ_AVIF_FUZZTEST_HELPERS_H_ |
6 | | |
7 | | #include <cstdint> |
8 | | #include <cstdlib> |
9 | | #include <limits> |
10 | | #include <type_traits> |
11 | | #include <utility> |
12 | | #include <vector> |
13 | | |
14 | | #include "avif/avif.h" |
15 | | #include "aviftest_helpers.h" |
16 | | #include "avifutil.h" |
17 | | #include "fuzztest/fuzztest.h" |
18 | | #include "gtest/gtest.h" |
19 | | |
20 | | namespace avif { |
21 | | |
22 | | //------------------------------------------------------------------------------ |
23 | | // Custom FuzzTest printer for libavif types. Needed to avoid compile-time |
24 | | // errors due to structs with C-style array fields. |
25 | | // |
26 | | // These should reside in the same namespace as the types they print to enable |
27 | | // Argument-Dependent Lookup (ADL). |
28 | | // See https://github.com/google/fuzztest/blob/main/doc/domains-reference.md. |
29 | | template <typename Sink, typename Ptr, |
30 | | typename = std::enable_if_t<std::is_same_v<Ptr, ImagePtr> || |
31 | | std::is_same_v<Ptr, EncoderPtr> || |
32 | | std::is_same_v<Ptr, DecoderPtr>>> |
33 | | void FuzzTestPrintSourceCode(Sink& sink, const Ptr& ptr) { |
34 | | // Stub to avoid compile error for structs with C-style array fields. |
35 | | // Consider adding a useful source code representation here: |
36 | | // `absl::Format(&sink, ...);` |
37 | | } |
38 | | |
39 | | namespace testutil { |
40 | | |
41 | | //------------------------------------------------------------------------------ |
42 | | // C++ wrapper for scoped memory management of C API objects. |
43 | | |
44 | | // Exposed for convenient fuzztest reproducer output. |
45 | | ImagePtr CreateAvifImage8b(size_t width, size_t height, |
46 | | avifPixelFormat pixel_format, bool has_alpha, |
47 | | const std::vector<uint8_t>& samples); |
48 | | ImagePtr CreateAvifImage16b(size_t width, size_t height, int depth, |
49 | | avifPixelFormat pixel_format, bool has_alpha, |
50 | | const std::vector<uint16_t>& samples); |
51 | | std::vector<ImagePtr> CreateAvifAnim8b(size_t num_frames, size_t width, |
52 | | size_t height, |
53 | | avifPixelFormat pixel_format, |
54 | | bool has_alpha, |
55 | | const std::vector<uint8_t>& samples); |
56 | | std::vector<ImagePtr> CreateAvifAnim16b(size_t num_frames, size_t width, |
57 | | size_t height, int depth, |
58 | | avifPixelFormat pixel_format, |
59 | | bool has_alpha, |
60 | | const std::vector<uint16_t>& samples); |
61 | | EncoderPtr CreateAvifEncoder(avifCodecChoice codec_choice, int max_threads, |
62 | | int min_quantizer, int max_quantizer, |
63 | | int min_quantizer_alpha, int max_quantizer_alpha, |
64 | | int tile_rows_log2, int tile_cols_log2, int speed); |
65 | | DecoderPtr CreateAvifDecoder(avifCodecChoice codec_choice, int max_threads, |
66 | | avifDecoderSource requested_source, |
67 | | bool allow_progressive, bool allow_incremental, |
68 | | bool ignore_exif, bool ignore_xmp, |
69 | | uint32_t image_size_limit, |
70 | | uint32_t image_dimension_limit, |
71 | | uint32_t image_count_limit, |
72 | | avifStrictFlags strict_flags); |
73 | | DecoderPtr AddGainMapOptionsToDecoder( |
74 | | DecoderPtr decoder, avifImageContentTypeFlags image_content_to_decode); |
75 | | |
76 | | //------------------------------------------------------------------------------ |
77 | | // Custom fuzztest generators. |
78 | | // See https://github.com/google/fuzztest/blob/main/doc/domains-reference.md. |
79 | | |
80 | | // Do not generate images wider or taller than this. |
81 | | inline constexpr size_t kMaxDimension = 512; // In pixels. |
82 | | |
83 | | // Used to reduce kMaxDimension to keep the same complexity as a still image. |
84 | | inline constexpr size_t kMaxNumFramesSquareRoot = 2; |
85 | | // Do not generate animations with more than this number of frames. |
86 | | inline constexpr size_t kMaxNumFrames = |
87 | | kMaxNumFramesSquareRoot * kMaxNumFramesSquareRoot; |
88 | | |
89 | | size_t GetNumSamples(size_t num_frames, size_t width, size_t height, |
90 | | avifPixelFormat pixel_format, bool has_alpha); |
91 | | |
92 | | // To avoid using fuzztest::internal, the return type of the functions below is |
93 | | // auto. |
94 | | |
95 | 38 | inline auto ArbitraryPixelFormat() { |
96 | 38 | return fuzztest::ElementOf<avifPixelFormat>( |
97 | 38 | {AVIF_PIXEL_FORMAT_YUV444, AVIF_PIXEL_FORMAT_YUV422, |
98 | 38 | AVIF_PIXEL_FORMAT_YUV420, AVIF_PIXEL_FORMAT_YUV400}); |
99 | 38 | } |
100 | | |
101 | | // avifImage generator type: Width, height, pixel format and 8-bit samples. |
102 | 16 | inline auto ArbitraryAvifImage8b() { |
103 | 16 | return fuzztest::FlatMap( |
104 | 16 | [](size_t width, size_t height, avifPixelFormat pixel_format, |
105 | 82.1k | bool has_alpha) { |
106 | 82.1k | return fuzztest::Map( |
107 | 82.1k | CreateAvifImage8b, fuzztest::Just(width), fuzztest::Just(height), |
108 | 82.1k | fuzztest::Just(pixel_format), fuzztest::Just(has_alpha), |
109 | 82.1k | fuzztest::Arbitrary<std::vector<uint8_t>>().WithSize(GetNumSamples( |
110 | 82.1k | /*num_frames=*/1, width, height, pixel_format, has_alpha))); |
111 | 82.1k | }, |
112 | 16 | fuzztest::InRange<uint16_t>(1, kMaxDimension), |
113 | 16 | fuzztest::InRange<uint16_t>(1, kMaxDimension), ArbitraryPixelFormat(), |
114 | 16 | fuzztest::Arbitrary<bool>()); |
115 | 16 | } |
116 | | |
117 | | // avifImage generator type: Width, height, depth, pixel format and 16-bit |
118 | | // samples. |
119 | 16 | inline auto ArbitraryAvifImage16b() { |
120 | 16 | return fuzztest::FlatMap( |
121 | 16 | [](size_t width, size_t height, int depth, avifPixelFormat pixel_format, |
122 | 54.1k | bool has_alpha) { |
123 | 54.1k | return fuzztest::Map( |
124 | 54.1k | CreateAvifImage16b, fuzztest::Just(width), fuzztest::Just(height), |
125 | 54.1k | fuzztest::Just(depth), fuzztest::Just(pixel_format), |
126 | 54.1k | fuzztest::Just(has_alpha), |
127 | 54.1k | fuzztest::ContainerOf<std::vector<uint16_t>>( |
128 | 54.1k | fuzztest::InRange<uint16_t>(0, (1 << depth) - 1)) |
129 | 54.1k | .WithSize(GetNumSamples(/*num_frames=*/1, width, height, |
130 | 54.1k | pixel_format, has_alpha))); |
131 | 54.1k | }, |
132 | 16 | fuzztest::InRange<uint16_t>(1, kMaxDimension), |
133 | 16 | fuzztest::InRange<uint16_t>(1, kMaxDimension), |
134 | 16 | fuzztest::ElementOf({10, 12}), ArbitraryPixelFormat(), |
135 | 16 | fuzztest::Arbitrary<bool>()); |
136 | 16 | } |
137 | | |
138 | | // avifImage generator type: Number of frames, width, height, pixel format and |
139 | | // 8-bit samples. |
140 | 2 | inline auto ArbitraryAvifAnim8b() { |
141 | 2 | return fuzztest::FlatMap( |
142 | 2 | [](size_t num_frames, size_t width, size_t height, |
143 | 33.9k | avifPixelFormat pixel_format, bool has_alpha) { |
144 | 33.9k | return fuzztest::Map( |
145 | 33.9k | CreateAvifAnim8b, fuzztest::Just(num_frames), fuzztest::Just(width), |
146 | 33.9k | fuzztest::Just(height), fuzztest::Just(pixel_format), |
147 | 33.9k | fuzztest::Just(has_alpha), |
148 | 33.9k | fuzztest::Arbitrary<std::vector<uint8_t>>().WithSize(GetNumSamples( |
149 | 33.9k | num_frames, width, height, pixel_format, has_alpha))); |
150 | 33.9k | }, |
151 | 2 | fuzztest::InRange<uint16_t>(1, kMaxNumFrames), |
152 | 2 | fuzztest::InRange<uint16_t>(1, kMaxDimension / kMaxNumFramesSquareRoot), |
153 | 2 | fuzztest::InRange<uint16_t>(1, kMaxDimension / kMaxNumFramesSquareRoot), |
154 | 2 | ArbitraryPixelFormat(), fuzztest::Arbitrary<bool>()); |
155 | 2 | } |
156 | | |
157 | | // avifImage generator type: Number of frames, width, height, depth, pixel |
158 | | // format and 16-bit samples. |
159 | 2 | inline auto ArbitraryAvifAnim16b() { |
160 | 2 | return fuzztest::FlatMap( |
161 | 2 | [](size_t num_frames, size_t width, size_t height, int depth, |
162 | 14.7k | avifPixelFormat pixel_format, bool has_alpha) { |
163 | 14.7k | return fuzztest::Map( |
164 | 14.7k | CreateAvifAnim16b, fuzztest::Just(num_frames), |
165 | 14.7k | fuzztest::Just(width), fuzztest::Just(height), |
166 | 14.7k | fuzztest::Just(depth), fuzztest::Just(pixel_format), |
167 | 14.7k | fuzztest::Just(has_alpha), |
168 | 14.7k | fuzztest::ContainerOf<std::vector<uint16_t>>( |
169 | 14.7k | fuzztest::InRange<uint16_t>(0, (1 << depth) - 1)) |
170 | 14.7k | .WithSize(GetNumSamples(num_frames, width, height, pixel_format, |
171 | 14.7k | has_alpha))); |
172 | 14.7k | }, |
173 | 2 | fuzztest::InRange<uint16_t>(1, kMaxNumFrames), |
174 | 2 | fuzztest::InRange<uint16_t>(1, kMaxDimension / kMaxNumFramesSquareRoot), |
175 | 2 | fuzztest::InRange<uint16_t>(1, kMaxDimension / kMaxNumFramesSquareRoot), |
176 | 2 | fuzztest::ElementOf({10, 12}), ArbitraryPixelFormat(), |
177 | 2 | fuzztest::Arbitrary<bool>()); |
178 | 2 | } |
179 | | |
180 | | // Generator for an arbitrary ImagePtr. |
181 | 16 | inline auto ArbitraryAvifImage() { |
182 | 16 | return fuzztest::OneOf(ArbitraryAvifImage8b(), ArbitraryAvifImage16b()); |
183 | 16 | } |
184 | | |
185 | | // Generator for an arbitrary std::vector<ImagePtr>. |
186 | 2 | inline auto ArbitraryAvifAnim() { |
187 | 2 | return fuzztest::OneOf(ArbitraryAvifAnim8b(), ArbitraryAvifAnim16b()); |
188 | 2 | } |
189 | | |
190 | | // Generates two signed fractions where the first one is smaller than or equal |
191 | | // to the second one. |
192 | 12 | inline auto ArbitraryMinMaxSignedFraction() { |
193 | 12 | return fuzztest::FlatMap( |
194 | 29.2k | [](int32_t max_n, uint32_t max_d) { |
195 | 29.2k | return fuzztest::Map( |
196 | 29.2k | [max_n, max_d](int32_t min_n) { |
197 | | // For simplicity, use the same denominator for both fractions. |
198 | | // This does not cover all possible fractions but makes it easy |
199 | | // to guarantee that the first fraction is smaller. |
200 | 9.68k | return std::pair<avifSignedFraction, avifSignedFraction>( |
201 | 9.68k | {min_n, max_d}, {max_n, max_d}); |
202 | 9.68k | }, |
203 | 29.2k | fuzztest::InRange<int32_t>(std::numeric_limits<int32_t>::min(), |
204 | 29.2k | max_n)); |
205 | 29.2k | }, |
206 | 12 | fuzztest::Arbitrary<int32_t>(), fuzztest::NonZero<uint32_t>()); |
207 | 12 | } |
208 | | |
209 | | ImagePtr AddGainMapToImage( |
210 | | ImagePtr image, ImagePtr gain_map, |
211 | | const std::pair<avifSignedFraction, avifSignedFraction>& gain_map_min_max0, |
212 | | const std::pair<avifSignedFraction, avifSignedFraction>& gain_map_min_max1, |
213 | | const std::pair<avifSignedFraction, avifSignedFraction>& gain_map_min_max2, |
214 | | uint32_t gain_map_gamma_n0, uint32_t gain_map_gamma_n1, |
215 | | uint32_t gain_map_gamma_n2, uint32_t gain_map_gamma_d0, |
216 | | uint32_t gain_map_gamma_d1, uint32_t gain_map_gamma_d2, |
217 | | int32_t base_offset_n0, int32_t base_offset_n1, int32_t base_offset_n2, |
218 | | uint32_t base_offset_d0, uint32_t base_offset_d1, uint32_t base_offset_d2, |
219 | | int32_t alternate_offset_n0, int32_t alternate_offset_n1, |
220 | | int32_t alternate_offset_n2, uint32_t alternate_offset_d0, |
221 | | uint32_t alternate_offset_d1, uint32_t alternate_offset_d2, |
222 | | uint32_t base_hdr_headroom_n, uint32_t base_hdr_headroom_d, |
223 | | uint32_t alternate_hdr_headroom_n, uint32_t alternate_hdr_headroom_d, |
224 | | bool use_base_color_space); |
225 | | |
226 | 4 | inline auto ArbitraryAvifImageWithGainMap() { |
227 | 4 | return fuzztest::Map( |
228 | 4 | AddGainMapToImage, ArbitraryAvifImage(), |
229 | 4 | /*gain_map=*/ArbitraryAvifImage(), |
230 | 4 | /*gain_map_min_max0=*/ArbitraryMinMaxSignedFraction(), |
231 | 4 | /*gain_map_min_max1=*/ArbitraryMinMaxSignedFraction(), |
232 | 4 | /*gain_map_min_max2=*/ArbitraryMinMaxSignedFraction(), |
233 | 4 | /*gain_map_gamma_n0=*/fuzztest::NonZero<uint32_t>(), |
234 | 4 | /*gain_map_gamma_n1=*/fuzztest::NonZero<uint32_t>(), |
235 | 4 | /*gain_map_gamma_n2=*/fuzztest::NonZero<uint32_t>(), |
236 | 4 | /*gain_map_gamma_d0=*/fuzztest::NonZero<uint32_t>(), |
237 | 4 | /*gain_map_gamma_d1=*/fuzztest::NonZero<uint32_t>(), |
238 | 4 | /*gain_map_gamma_d2=*/fuzztest::NonZero<uint32_t>(), |
239 | 4 | /*base_offset_n0=*/fuzztest::Arbitrary<int32_t>(), |
240 | 4 | /*base_offset_n1=*/fuzztest::Arbitrary<int32_t>(), |
241 | 4 | /*base_offset_n2=*/fuzztest::Arbitrary<int32_t>(), |
242 | 4 | /*base_offset_d0=*/fuzztest::NonZero<uint32_t>(), |
243 | 4 | /*base_offset_d1=*/fuzztest::NonZero<uint32_t>(), |
244 | 4 | /*base_offset_d2=*/fuzztest::NonZero<uint32_t>(), |
245 | 4 | /*alternate_offset_n0=*/fuzztest::Arbitrary<int32_t>(), |
246 | 4 | /*alternate_offset_n1=*/fuzztest::Arbitrary<int32_t>(), |
247 | 4 | /*alternate_offset_n2=*/fuzztest::Arbitrary<int32_t>(), |
248 | 4 | /*alternate_offset_d0=*/fuzztest::NonZero<uint32_t>(), |
249 | 4 | /*alternate_offset_d1=*/fuzztest::NonZero<uint32_t>(), |
250 | 4 | /*alternate_offset_d2=*/fuzztest::NonZero<uint32_t>(), |
251 | 4 | /*base_hdr_headroom_n=*/fuzztest::Arbitrary<uint32_t>(), |
252 | 4 | /*base_hdr_headroom_d=*/fuzztest::NonZero<uint32_t>(), |
253 | 4 | /*alternate_hdr_headroom_n=*/fuzztest::Arbitrary<uint32_t>(), |
254 | 4 | /*alternate_hdr_headroom_d=*/fuzztest::NonZero<uint32_t>(), |
255 | 4 | /*use_base_color_space=*/fuzztest::Arbitrary<bool>()); |
256 | 4 | } |
257 | | |
258 | | // Generator for an arbitrary EncoderPtr. |
259 | 8 | inline auto ArbitraryAvifEncoder() { |
260 | 8 | const auto codec_choice = fuzztest::ElementOf<avifCodecChoice>( |
261 | 8 | {AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_CHOICE_AOM}); |
262 | | // MAX_NUM_THREADS from libaom/aom_util/aom_thread.h |
263 | 8 | const auto max_threads = fuzztest::InRange(0, 64); |
264 | 8 | const auto min_quantizer = fuzztest::InRange(AVIF_QUANTIZER_BEST_QUALITY, |
265 | 8 | AVIF_QUANTIZER_WORST_QUALITY); |
266 | 8 | const auto max_quantizer = fuzztest::InRange(AVIF_QUANTIZER_BEST_QUALITY, |
267 | 8 | AVIF_QUANTIZER_WORST_QUALITY); |
268 | 8 | const auto min_quantizer_alpha = fuzztest::InRange( |
269 | 8 | AVIF_QUANTIZER_BEST_QUALITY, AVIF_QUANTIZER_WORST_QUALITY); |
270 | 8 | const auto max_quantizer_alpha = fuzztest::InRange( |
271 | 8 | AVIF_QUANTIZER_BEST_QUALITY, AVIF_QUANTIZER_WORST_QUALITY); |
272 | 8 | const auto tile_rows_log2 = fuzztest::InRange(0, 6); |
273 | 8 | const auto tile_cols_log2 = fuzztest::InRange(0, 6); |
274 | | // Fuzz only a small range of 'speed' values to avoid slowing down the fuzzer |
275 | | // too much. The main goal is to fuzz libavif, not the underlying AV1 encoder. |
276 | 8 | const auto speed = fuzztest::InRange(6, AVIF_SPEED_FASTEST); |
277 | 8 | return fuzztest::Map(CreateAvifEncoder, codec_choice, max_threads, |
278 | 8 | min_quantizer, max_quantizer, min_quantizer_alpha, |
279 | 8 | max_quantizer_alpha, tile_rows_log2, tile_cols_log2, |
280 | 8 | speed); |
281 | 8 | } |
282 | | |
283 | | // Generator for an arbitrary DecoderPtr with base options fuzzed (i.e. |
284 | | // without "experimental" options hidden behind compile flags). |
285 | 16 | inline auto ArbitraryBaseAvifDecoder() { |
286 | | // MAX_NUM_THREADS from libaom/aom_util/aom_thread.h |
287 | 16 | const auto max_threads = fuzztest::InRange(0, 64); |
288 | 16 | return fuzztest::Map( |
289 | 16 | CreateAvifDecoder, |
290 | 16 | fuzztest::ElementOf<avifCodecChoice>({AVIF_CODEC_CHOICE_AUTO, |
291 | 16 | AVIF_CODEC_CHOICE_AOM, |
292 | 16 | AVIF_CODEC_CHOICE_DAV1D}), |
293 | 16 | max_threads, |
294 | | /*requested_source=*/ |
295 | 16 | fuzztest::ElementOf( |
296 | 16 | {AVIF_DECODER_SOURCE_AUTO, AVIF_DECODER_SOURCE_PRIMARY_ITEM}), |
297 | 16 | /*allow_progressive=*/fuzztest::Arbitrary<bool>(), |
298 | 16 | /*allow_incremental=*/fuzztest::Arbitrary<bool>(), |
299 | 16 | /*ignore_exif=*/fuzztest::Arbitrary<bool>(), |
300 | 16 | /*ignore_xmp=*/fuzztest::Arbitrary<bool>(), |
301 | 16 | /*image_size_limit=*/fuzztest::Just(kMaxDimension * kMaxDimension), |
302 | 16 | /*image_dimension_limit=*/fuzztest::Just(kMaxDimension), |
303 | 16 | /*image_count_limit=*/fuzztest::Just(10), |
304 | | /*strict_flags=*/ |
305 | 16 | fuzztest::BitFlagCombinationOf<avifStrictFlags>( |
306 | 16 | {AVIF_STRICT_PIXI_REQUIRED, AVIF_STRICT_CLAP_VALID, |
307 | 16 | AVIF_STRICT_ALPHA_ISPE_REQUIRED})); |
308 | 16 | } |
309 | | |
310 | | // Generator for an arbitrary DecoderPtr with base options and gain map |
311 | | // options fuzzed. |
312 | 8 | inline auto ArbitraryAvifDecoderWithGainMapOptions() { |
313 | | // Always decode at least color+alpha, since most tests |
314 | | // assume that if the file/buffer is successfully decoded. |
315 | 8 | return fuzztest::Map( |
316 | 8 | AddGainMapOptionsToDecoder, ArbitraryBaseAvifDecoder(), |
317 | 8 | fuzztest::ElementOf<avifImageContentTypeFlags>( |
318 | 8 | {AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA, |
319 | 8 | AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | AVIF_IMAGE_CONTENT_GAIN_MAP, |
320 | 8 | AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | |
321 | 8 | AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS, |
322 | 8 | AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | AVIF_IMAGE_CONTENT_GAIN_MAP | |
323 | 8 | AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS})); |
324 | 8 | } |
325 | | |
326 | | // Generator for an arbitrary DecoderPtr. |
327 | 8 | inline auto ArbitraryAvifDecoder() { |
328 | 8 | return ArbitraryAvifDecoderWithGainMapOptions(); |
329 | 8 | } |
330 | | |
331 | | // Same as ArbitraryAvifDecoder() but imageContentToDecode can be set to |
332 | | // AVIF_IMAGE_CONTENT_NONE. |
333 | 8 | inline auto ArbitraryAvifDecoderPossiblyNoContent() { |
334 | 8 | return fuzztest::Map( |
335 | 8 | AddGainMapOptionsToDecoder, ArbitraryBaseAvifDecoder(), |
336 | 8 | fuzztest::BitFlagCombinationOf<avifImageContentTypeFlags>( |
337 | 8 | {AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA, AVIF_IMAGE_CONTENT_GAIN_MAP})); |
338 | 8 | } |
339 | | |
340 | | //------------------------------------------------------------------------------ |
341 | | |
342 | | // Returns the paths contained in the 'TEST_DATA_DIRS' environment variable. |
343 | | // Several paths can be set in the variable, separated by ';'. |
344 | | // Returns nullptr if not set. |
345 | | // Tests that use ArbitraryImageWithSeeds() should |
346 | | // ASSERT_FALSE(GetSeedDataDirs().empty()) if they want to make sure that seeds |
347 | | // are actually used. |
348 | | std::vector<std::string> GetSeedDataDirs(); |
349 | | |
350 | | // Returns a list of test images contents (not paths) from the directory set in |
351 | | // the 'TEST_DATA_DIRS' environment variable, that are smaller than |
352 | | // 'max_file_size' and have one of the formats in 'image_formats' (or any format |
353 | | // if 'image_formats' is empty). |
354 | | // If TEST_DATA_DIRS is not set, returns an empty set. |
355 | | // Tests that use this should ASSERT_FALSE(GetSeedDataDirs().empty()) |
356 | | // if they want to make sure that seeds are actually used. |
357 | | // Terminates the program with abort() if TEST_DATA_DIRS is set but doesn't |
358 | | // contain any matching images. |
359 | | std::vector<std::string> GetTestImagesContents( |
360 | | size_t max_file_size, const std::vector<avifAppFileFormat>& image_formats); |
361 | | |
362 | | // Generator for an arbitrary ImagePtr that uses test image files as seeds. |
363 | | // Uses the 'TEST_DATA_DIRS' environment variable to load the seeds. |
364 | | // If TEST_DATA_DIRS is not set, no seeds are used. |
365 | | // Tests that use this should ASSERT_FALSE(GetSeedDataDirs().empty()) |
366 | | // if they want to make sure that seeds are actually used. |
367 | | // Terminates the program with abort() if TEST_DATA_DIRS is set but doesn't |
368 | | // contain any matching images. |
369 | | inline auto ArbitraryImageWithSeeds( |
370 | 12 | const std::vector<avifAppFileFormat>& image_formats) { |
371 | 12 | constexpr uint32_t kMaxSeedFileSize = 1024 * 1024; // 1MB. |
372 | 12 | return fuzztest::Arbitrary<std::string>() |
373 | 12 | .WithMaxSize(kMaxSeedFileSize) |
374 | 12 | .WithSeeds(GetTestImagesContents(kMaxSeedFileSize, image_formats)); |
375 | 12 | } |
376 | | |
377 | | //------------------------------------------------------------------------------ |
378 | | |
379 | | } // namespace testutil |
380 | | } // namespace avif |
381 | | |
382 | | #endif // LIBAVIF_TESTS_OSS_FUZZ_AVIF_FUZZTEST_HELPERS_H_ |