blob: 928026dac06ec6f630118f6e5bc0db7ea523a359 [file] [log] [blame] [edit]
// Copyright 2022 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
// Encode a fuzzed image split into a grid and decode it incrementally.
// Compare the output with a non-incremental decode.
#include <cassert>
#include <cstdint>
#include <vector>
#include "avif/internal.h"
#include "avif_fuzztest_helpers.h"
#include "avifincrtest_helpers.h"
#include "aviftest_helpers.h"
#include "fuzztest/fuzztest.h"
#include "gtest/gtest.h"
using ::fuzztest::Arbitrary;
using ::fuzztest::InRange;
namespace libavif {
namespace testutil {
namespace {
::testing::Environment* const stack_limit_env =
::testing::AddGlobalTestEnvironment(
new FuzztestStackLimitEnvironment("524288")); // 512 * 1024
// Encodes an image into an AVIF grid then decodes it.
void EncodeDecodeGridValid(AvifImagePtr image, AvifEncoderPtr encoder,
AvifDecoderPtr decoder, uint32_t grid_cols,
uint32_t grid_rows, bool is_encoded_data_persistent,
bool give_size_hint_to_decoder) {
ASSERT_NE(image, nullptr);
ASSERT_NE(encoder, nullptr);
const std::vector<AvifImagePtr> cells =
ImageToGrid(image.get(), grid_cols, grid_rows);
if (cells.empty()) return;
const uint32_t cell_width = cells.front()->width;
const uint32_t cell_height = cells.front()->height;
const uint32_t encoded_width = std::min(image->width, grid_cols * cell_width);
const uint32_t encoded_height =
std::min(image->height, grid_rows * cell_height);
AvifRwData encoded_data;
const avifResult encoder_result = avifEncoderAddImageGrid(
encoder.get(), grid_cols, grid_rows, UniquePtrToRawPtr(cells).data(),
AVIF_ADD_IMAGE_FLAG_SINGLE);
if (((grid_cols > 1 || grid_rows > 1) &&
!avifAreGridDimensionsValid(image->yuvFormat, encoded_width,
encoded_height, cell_width, cell_height,
nullptr))) {
ASSERT_TRUE(encoder_result == AVIF_RESULT_INVALID_IMAGE_GRID)
<< avifResultToString(encoder_result);
return;
}
ASSERT_EQ(encoder_result, AVIF_RESULT_OK)
<< avifResultToString(encoder_result);
const avifResult finish_result =
avifEncoderFinish(encoder.get(), &encoded_data);
ASSERT_EQ(finish_result, AVIF_RESULT_OK) << avifResultToString(finish_result);
DecodeNonIncrementallyAndIncrementally(encoded_data, decoder.get(),
is_encoded_data_persistent,
give_size_hint_to_decoder,
/*useNthImageApi=*/true, cell_height);
}
FUZZ_TEST(EncodeDecodeAvifFuzzTest, EncodeDecodeGridValid)
.WithDomains(ArbitraryAvifImage(), ArbitraryAvifEncoder(),
ArbitraryAvifDecoder({AVIF_CODEC_CHOICE_AUTO}),
/*grid_cols=*/InRange<uint32_t>(1, 32),
/*grid_rows=*/InRange<uint32_t>(1, 32),
/*is_encoded_data_persistent=*/Arbitrary<bool>(),
/*give_size_hint_to_decoder=*/Arbitrary<bool>());
} // namespace
} // namespace testutil
} // namespace libavif