blob: 14917f3cebe1fa7b54cab53d79373ae3a43b83d1 [file] [log] [blame]
// 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 avif {
namespace testutil {
namespace {
::testing::Environment* const kStackLimitEnv = SetStackLimitTo512x1024Bytes();
// Encodes an image into an AVIF grid then decodes it.
void EncodeDecodeGridValid(ImagePtr image, EncoderPtr encoder,
DecoderPtr 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<ImagePtr> 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);
const avifResult decode_result = DecodeNonIncrementallyAndIncrementally(
encoded_data, decoder.get(), is_encoded_data_persistent,
give_size_hint_to_decoder, /*use_nth_image_api=*/true, cell_height);
ASSERT_EQ(decode_result, AVIF_RESULT_OK) << avifResultToString(decode_result);
}
FUZZ_TEST(EncodeDecodeAvifFuzzTest, EncodeDecodeGridValid)
.WithDomains(ArbitraryAvifImage(), ArbitraryAvifEncoder(),
ArbitraryAvifDecoder(),
/*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 avif