blob: 6a28f417cd0af9a79aa9edd4438bb68722c3dca0 [file] [log] [blame]
// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
#include <cstring>
#include "avif/avif.h"
#include "avif_fuzztest_helpers.h"
#include "aviftest_helpers.h"
#include "fuzztest/fuzztest.h"
#include "gtest/gtest.h"
using ::fuzztest::Arbitrary;
using ::fuzztest::ElementOf;
using ::fuzztest::InRange;
namespace avif {
namespace testutil {
namespace {
void Convert(ImagePtr image, int rgb_depth, int rgb_format,
avifChromaUpsampling upsampling,
avifChromaDownsampling downsampling, bool avoid_libyuv,
bool ignore_alpha, bool alpha_premultiplied, bool is_float,
int max_threads) {
AvifRgbImage rgb(image.get(), rgb_depth,
static_cast<avifRGBFormat>(rgb_format));
rgb.chromaUpsampling = upsampling;
rgb.chromaDownsampling = downsampling;
rgb.avoidLibYUV = avoid_libyuv;
rgb.ignoreAlpha = ignore_alpha;
rgb.alphaPremultiplied = alpha_premultiplied;
rgb.isFloat = is_float;
rgb.maxThreads = max_threads;
// See avifRGBFormat and avifRGBImage.
const avifResult expected_yuv_to_rgb_result =
(rgb_format == AVIF_RGB_FORMAT_RGB_565 && rgb_depth != 8)
? AVIF_RESULT_REFORMAT_FAILED
: (is_float && rgb_depth != 16) ? AVIF_RESULT_REFORMAT_FAILED
: (max_threads < 0) ? AVIF_RESULT_REFORMAT_FAILED
: AVIF_RESULT_OK;
const avifResult expected_rgb_to_yuv_result =
(rgb_format == AVIF_RGB_FORMAT_RGB_565) ? AVIF_RESULT_REFORMAT_FAILED
: (is_float && rgb_depth != 16) ? AVIF_RESULT_REFORMAT_FAILED
: (is_float) ? AVIF_RESULT_NOT_IMPLEMENTED
: AVIF_RESULT_OK;
ASSERT_EQ(avifImageYUVToRGB(image.get(), &rgb), expected_yuv_to_rgb_result);
if (expected_yuv_to_rgb_result != AVIF_RESULT_OK) {
// Fill pixels with something, so that avifImageRGBToYUV() can be called.
AvifRgbImage rgb_ok(image.get(), rgb_depth, AVIF_RGB_FORMAT_RGBA);
ASSERT_EQ(avifImageYUVToRGB(image.get(), &rgb_ok), AVIF_RESULT_OK);
std::memcpy(rgb.pixels, rgb_ok.pixels, rgb.rowBytes * rgb.height);
}
ASSERT_EQ(avifImageRGBToYUV(image.get(), &rgb), expected_rgb_to_yuv_result);
}
FUZZ_TEST(YuvRgbFuzzTest, Convert)
.WithDomains(ArbitraryAvifImage(),
/*rgb_depth=*/ElementOf({8, 10, 12, 16}),
InRange(0, int{AVIF_RGB_FORMAT_COUNT} - 1),
ElementOf({AVIF_CHROMA_UPSAMPLING_AUTOMATIC,
AVIF_CHROMA_UPSAMPLING_FASTEST,
AVIF_CHROMA_UPSAMPLING_BEST_QUALITY,
AVIF_CHROMA_UPSAMPLING_NEAREST,
AVIF_CHROMA_UPSAMPLING_BILINEAR}),
ElementOf({AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC,
AVIF_CHROMA_DOWNSAMPLING_FASTEST,
AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY,
AVIF_CHROMA_DOWNSAMPLING_AVERAGE,
AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV}),
/*avoid_libyuv=*/Arbitrary<bool>(),
/*ignore_alpha=*/Arbitrary<bool>(),
/*alpha_premultiplied=*/Arbitrary<bool>(),
/*is_float=*/Arbitrary<bool>(),
/*max_threads=*/ElementOf({-1, 0, 1, 2, 8}));
//------------------------------------------------------------------------------
} // namespace
} // namespace testutil
} // namespace avif