blob: 63099619a38a1b4c2bd9da4f01d8d1a373cf35c6 [file] [log] [blame]
// Copyright 2022 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
#include <iostream>
#include <string>
#include <tuple>
#include "avif/avif.h"
#include "avifincrtest_helpers.h"
#include "aviftest_helpers.h"
#include "gtest/gtest.h"
using testing::Bool;
using testing::Combine;
using testing::Values;
namespace avif {
namespace {
// Used to pass the data folder path to the GoogleTest suites.
const char* data_path = nullptr;
//------------------------------------------------------------------------------
// Check that non-incremental and incremental decodings of a grid AVIF produce
// the same pixels.
TEST(IncrementalTest, Decode) {
const testutil::AvifRwData encoded_avif =
testutil::ReadFile(std::string(data_path) + "sofa_grid1x5_420.avif");
ASSERT_NE(encoded_avif.size, 0u);
ImagePtr reference(avifImageCreateEmpty());
ASSERT_NE(reference, nullptr);
DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
ASSERT_EQ(avifDecoderReadMemory(decoder.get(), reference.get(),
encoded_avif.data, encoded_avif.size),
AVIF_RESULT_OK);
// Cell height is hardcoded because there is no API to extract it from an
// encoded payload.
ASSERT_EQ(testutil::DecodeIncrementally(
encoded_avif, decoder.get(),
/*is_persistent=*/true, /*give_size_hint=*/true,
/*use_nth_image_api=*/false, *reference,
/*cell_height=*/154,
/*enable_fine_incremental_check=*/true),
AVIF_RESULT_OK);
}
//------------------------------------------------------------------------------
class IncrementalTest
: public testing::TestWithParam<std::tuple<
/*width=*/uint32_t, /*height=*/uint32_t, /*create_alpha=*/bool,
/*flat_cells=*/bool, /*encoded_avif_is_persistent=*/bool,
/*give_size_hint=*/bool, /*use_nth_image_api=*/bool>> {};
// Encodes then decodes a window of width*height pixels at the middle of the
// image. Check that non-incremental and incremental decodings produce the same
// pixels.
TEST_P(IncrementalTest, EncodeDecode) {
const uint32_t width = std::get<0>(GetParam());
const uint32_t height = std::get<1>(GetParam());
const bool create_alpha = std::get<2>(GetParam());
const bool flat_cells = std::get<3>(GetParam());
const bool encoded_avif_is_persistent = std::get<4>(GetParam());
const bool give_size_hint = std::get<5>(GetParam());
const bool use_nth_image_api = std::get<6>(GetParam());
// Load an image. It does not matter that it comes from an AVIF file.
ImagePtr image(avifImageCreateEmpty());
ASSERT_NE(image, nullptr);
const testutil::AvifRwData image_bytes =
testutil::ReadFile(std::string(data_path) + "sofa_grid1x5_420.avif");
ASSERT_NE(image_bytes.size, 0u);
DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
ASSERT_EQ(avifDecoderReadMemory(decoder.get(), image.get(), image_bytes.data,
image_bytes.size),
AVIF_RESULT_OK);
// Encode then decode it.
testutil::AvifRwData encoded_avif;
uint32_t cell_width, cell_height;
testutil::EncodeRectAsIncremental(*image, width, height, create_alpha,
flat_cells, &encoded_avif, &cell_width,
&cell_height);
ASSERT_EQ(testutil::DecodeNonIncrementallyAndIncrementally(
encoded_avif, decoder.get(), encoded_avif_is_persistent,
give_size_hint, use_nth_image_api, cell_height,
/*enable_fine_incremental_check=*/true),
AVIF_RESULT_OK);
}
INSTANTIATE_TEST_SUITE_P(WholeImage, IncrementalTest,
Combine(/*width=*/Values(1024),
/*height=*/Values(770),
/*create_alpha=*/Values(true),
/*flat_cells=*/Bool(),
/*encoded_avif_is_persistent=*/Values(true),
/*give_size_hint=*/Values(true),
/*use_nth_image_api=*/Values(false)));
// avifEncoderAddImageInternal() only accepts grids of one unique cell, or grids
// where width and height are both at least 64.
INSTANTIATE_TEST_SUITE_P(SingleCell, IncrementalTest,
Combine(/*width=*/Values(1),
/*height=*/Values(1),
/*create_alpha=*/Bool(),
/*flat_cells=*/Bool(),
/*encoded_avif_is_persistent=*/Bool(),
/*give_size_hint=*/Bool(),
/*use_nth_image_api=*/Bool()));
// Chroma subsampling requires even dimensions. See ISO 23000-22
// section 7.3.11.4.2.
INSTANTIATE_TEST_SUITE_P(SinglePixel, IncrementalTest,
Combine(/*width=*/Values(64, 66),
/*height=*/Values(64, 66),
/*create_alpha=*/Bool(),
/*flat_cells=*/Bool(),
/*encoded_avif_is_persistent=*/Bool(),
/*give_size_hint=*/Bool(),
/*use_nth_image_api=*/Bool()));
//------------------------------------------------------------------------------
} // namespace
} // namespace avif
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
if (argc < 2) {
std::cerr
<< "The path to the test data folder must be provided as an argument"
<< std::endl;
return 1;
}
avif::data_path = argv[1];
return RUN_ALL_TESTS();
}