/src/libavif/tests/gtest/avif_fuzztest_yuvrgb.cc
Line | Count | Source |
1 | | // Copyright 2023 Google LLC |
2 | | // SPDX-License-Identifier: BSD-2-Clause |
3 | | |
4 | | #include <cstring> |
5 | | |
6 | | #include "avif/avif.h" |
7 | | #include "avif_fuzztest_helpers.h" |
8 | | #include "aviftest_helpers.h" |
9 | | #include "fuzztest/fuzztest.h" |
10 | | #include "gtest/gtest.h" |
11 | | |
12 | | using ::fuzztest::Arbitrary; |
13 | | using ::fuzztest::ElementOf; |
14 | | using ::fuzztest::InRange; |
15 | | |
16 | | namespace avif { |
17 | | namespace testutil { |
18 | | namespace { |
19 | | |
20 | | void Convert(ImagePtr image, int rgb_depth, int rgb_format, |
21 | | avifChromaUpsampling upsampling, |
22 | | avifChromaDownsampling downsampling, bool avoid_libyuv, |
23 | | bool ignore_alpha, bool alpha_premultiplied, bool is_float, |
24 | 3.85k | int max_threads) { |
25 | 3.85k | AvifRgbImage rgb(image.get(), rgb_depth, |
26 | 3.85k | static_cast<avifRGBFormat>(rgb_format)); |
27 | 3.85k | rgb.chromaUpsampling = upsampling; |
28 | 3.85k | rgb.chromaDownsampling = downsampling; |
29 | 3.85k | rgb.avoidLibYUV = avoid_libyuv; |
30 | 3.85k | rgb.ignoreAlpha = ignore_alpha; |
31 | 3.85k | rgb.alphaPremultiplied = alpha_premultiplied; |
32 | 3.85k | rgb.isFloat = is_float; |
33 | 3.85k | rgb.maxThreads = max_threads; |
34 | | |
35 | | // See avifRGBFormat and avifRGBImage. |
36 | 3.85k | const avifResult expected_yuv_to_rgb_result = |
37 | 3.85k | (rgb_format == AVIF_RGB_FORMAT_RGB_565 && rgb_depth != 8) |
38 | 3.85k | ? AVIF_RESULT_REFORMAT_FAILED |
39 | 3.85k | : (is_float && rgb_depth != 16) ? AVIF_RESULT_REFORMAT_FAILED |
40 | 3.83k | : (max_threads < 0) ? AVIF_RESULT_REFORMAT_FAILED |
41 | 3.47k | : AVIF_RESULT_OK; |
42 | 3.85k | const avifResult expected_rgb_to_yuv_result = |
43 | 3.85k | (rgb_format == AVIF_RGB_FORMAT_RGB_565) ? AVIF_RESULT_REFORMAT_FAILED |
44 | 3.85k | : (is_float && rgb_depth != 16) ? AVIF_RESULT_REFORMAT_FAILED |
45 | 3.60k | : (is_float) ? AVIF_RESULT_NOT_IMPLEMENTED |
46 | 3.26k | : AVIF_RESULT_OK; |
47 | | |
48 | 3.85k | ASSERT_EQ(avifImageYUVToRGB(image.get(), &rgb), expected_yuv_to_rgb_result); |
49 | 3.85k | if (expected_yuv_to_rgb_result != AVIF_RESULT_OK) { |
50 | | // Fill pixels with something, so that avifImageRGBToYUV() can be called. |
51 | 1.13k | AvifRgbImage rgb_ok(image.get(), rgb_depth, AVIF_RGB_FORMAT_RGBA); |
52 | 1.13k | ASSERT_EQ(avifImageYUVToRGB(image.get(), &rgb_ok), AVIF_RESULT_OK); |
53 | 1.13k | std::memcpy(rgb.pixels, rgb_ok.pixels, rgb.rowBytes * rgb.height); |
54 | 1.13k | } |
55 | | |
56 | 3.85k | ASSERT_EQ(avifImageRGBToYUV(image.get(), &rgb), expected_rgb_to_yuv_result); |
57 | 3.85k | } |
58 | | |
59 | | FUZZ_TEST(YuvRgbFuzzTest, Convert) |
60 | | .WithDomains(ArbitraryAvifImage(), |
61 | | /*rgb_depth=*/ElementOf({8, 10, 12, 16}), |
62 | | InRange(0, int{AVIF_RGB_FORMAT_COUNT} - 1), |
63 | | ElementOf({AVIF_CHROMA_UPSAMPLING_AUTOMATIC, |
64 | | AVIF_CHROMA_UPSAMPLING_FASTEST, |
65 | | AVIF_CHROMA_UPSAMPLING_BEST_QUALITY, |
66 | | AVIF_CHROMA_UPSAMPLING_NEAREST, |
67 | | AVIF_CHROMA_UPSAMPLING_BILINEAR}), |
68 | | ElementOf({AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC, |
69 | | AVIF_CHROMA_DOWNSAMPLING_FASTEST, |
70 | | AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY, |
71 | | AVIF_CHROMA_DOWNSAMPLING_AVERAGE, |
72 | | AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV}), |
73 | | /*avoid_libyuv=*/Arbitrary<bool>(), |
74 | | /*ignore_alpha=*/Arbitrary<bool>(), |
75 | | /*alpha_premultiplied=*/Arbitrary<bool>(), |
76 | | /*is_float=*/Arbitrary<bool>(), |
77 | | /*max_threads=*/ElementOf({-1, 0, 1, 2, 8})); |
78 | | |
79 | | //------------------------------------------------------------------------------ |
80 | | |
81 | | } // namespace |
82 | | } // namespace testutil |
83 | | } // namespace avif |