testutil::ReadImage()
Use AvifImagePtr in avifmetadatatest.cc to fix C API memory leaks.
The aviftest_helpers target must be linked to avif_apps.
Use a STATIC avif_apps library instead of an OBJECT library to avoid
issues related to the lack of property transitivity in OBJECT libs.
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 2d3f75d..b328048 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -42,14 +42,12 @@
################################################################################
# GoogleTest
-if(AVIF_ENABLE_GTEST OR AVIF_BUILD_APPS)
+if(AVIF_ENABLE_GTEST)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 11)
add_library(aviftest_helpers OBJECT gtest/aviftest_helpers.cc)
- target_link_libraries(aviftest_helpers avif ${AVIF_PLATFORM_LIBRARIES})
-endif()
+ target_link_libraries(aviftest_helpers avif_apps)
-if(AVIF_ENABLE_GTEST)
if(AVIF_LOCAL_GTEST)
set(GTEST_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/ext/googletest/googletest/include)
set(GTEST_LIBRARIES
@@ -93,12 +91,12 @@
add_executable(avifincrtest gtest/avifincrtest.cc)
target_link_libraries(avifincrtest aviftest_helpers avifincrtest_helpers)
- add_test(NAME avifincrtest COMMAND avifincrtest ${CMAKE_CURRENT_SOURCE_DIR}/data)
+ add_test(NAME avifincrtest COMMAND avifincrtest ${CMAKE_CURRENT_SOURCE_DIR}/data/)
add_executable(avifmetadatatest gtest/avifmetadatatest.cc)
- target_link_libraries(avifmetadatatest aviftest_helpers avif_apps ${GTEST_LIBRARIES})
+ target_link_libraries(avifmetadatatest aviftest_helpers ${GTEST_LIBRARIES})
target_include_directories(avifmetadatatest PRIVATE ${GTEST_INCLUDE_DIRS})
- add_test(NAME avifmetadatatest COMMAND avifmetadatatest ${CMAKE_CURRENT_SOURCE_DIR}/data)
+ add_test(NAME avifmetadatatest COMMAND avifmetadatatest ${CMAKE_CURRENT_SOURCE_DIR}/data/)
add_executable(avifrgbtoyuvtest gtest/avifrgbtoyuvtest.cc)
target_link_libraries(avifrgbtoyuvtest aviftest_helpers ${GTEST_BOTH_LIBRARIES})
@@ -115,7 +113,7 @@
endif()
add_executable(avify4mtest gtest/avify4mtest.cc)
- target_link_libraries(avify4mtest aviftest_helpers avif_apps ${GTEST_BOTH_LIBRARIES})
+ target_link_libraries(avify4mtest aviftest_helpers ${GTEST_BOTH_LIBRARIES})
target_include_directories(avify4mtest PRIVATE ${GTEST_INCLUDE_DIRS})
add_test(NAME avify4mtest COMMAND avify4mtest)
else()
@@ -129,7 +127,7 @@
# When building apps, test the avifenc/avifdec.
# 'are_images_equal' is used to make sure inputs/outputs are unchanged.
add_executable(are_images_equal gtest/are_images_equal.cc)
- target_link_libraries(are_images_equal aviftest_helpers avif_apps)
+ target_link_libraries(are_images_equal aviftest_helpers)
add_test(NAME test_cmd COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/test_cmd.sh ${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/data
)
diff --git a/tests/gtest/avifmetadatatest.cc b/tests/gtest/avifmetadatatest.cc
index d70c983..4fe8cf7 100644
--- a/tests/gtest/avifmetadatatest.cc
+++ b/tests/gtest/avifmetadatatest.cc
@@ -6,7 +6,6 @@
#include "avif/avif.h"
#include "aviftest_helpers.h"
-#include "avifutil.h"
#include "gtest/gtest.h"
using ::testing::Bool;
@@ -113,8 +112,7 @@
// zTXt "Raw profile type exif" at the beginning of a PNG file.
TEST_P(MetadataTest, Read) {
- const std::string file_path =
- std::string(data_path) + "/" + std::get<0>(GetParam());
+ const char* file_name = std::get<0>(GetParam());
const bool use_icc = std::get<1>(GetParam());
const bool use_exif = std::get<2>(GetParam());
const bool use_xmp = std::get<3>(GetParam());
@@ -122,14 +120,12 @@
const bool expect_exif = std::get<5>(GetParam());
const bool expect_xmp = std::get<6>(GetParam());
- avifImage* image = avifImageCreateEmpty();
+ const testutil::AvifImagePtr image = testutil::ReadImage(
+ data_path, file_name, AVIF_PIXEL_FORMAT_NONE, 0, AVIF_RGB_TO_YUV_DEFAULT,
+ !use_icc, !use_exif, !use_xmp);
ASSERT_NE(image, nullptr);
- image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY; // lossless
- ASSERT_NE(avifReadImage(file_path.c_str(), AVIF_PIXEL_FORMAT_NONE, 0,
- AVIF_RGB_TO_YUV_DEFAULT, !use_icc, !use_exif,
- !use_xmp, image, nullptr, nullptr, nullptr),
- AVIF_APP_FILE_FORMAT_UNKNOWN);
EXPECT_NE(image->width * image->height, 0u);
+
if (expect_icc) {
EXPECT_NE(image->icc.size, 0u);
EXPECT_NE(image->icc.data, nullptr);
@@ -182,28 +178,21 @@
// Verify all parsers lead exactly to the same metadata bytes.
TEST(MetadataTest, Compare) {
- constexpr const char* kFileNames[] = {"paris_icc_exif_xmp.png",
- "paris_exif_xmp_icc.jpg",
- "paris_icc_exif_xmp_at_end.png"};
- avifImage* images[sizeof(kFileNames) / sizeof(kFileNames[0])];
- avifImage** image_it = images;
- for (const char* file_name : kFileNames) {
- const std::string file_path = std::string(data_path) + "/" + file_name;
+ const testutil::AvifImagePtr ref =
+ testutil::ReadImage(data_path, "paris_icc_exif_xmp.png");
+ ASSERT_NE(ref, nullptr);
+ EXPECT_GT(ref->exif.size, 0u);
+ EXPECT_GT(ref->xmp.size, 0u);
+ EXPECT_GT(ref->icc.size, 0u);
- *image_it = avifImageCreateEmpty();
- ASSERT_NE(*image_it, nullptr);
- ASSERT_NE(avifReadImage(file_path.c_str(), AVIF_PIXEL_FORMAT_NONE, 0,
- AVIF_RGB_TO_YUV_DEFAULT, /*ignoreICC=*/false,
- /*ignoreExif=*/false, /*ignoreXMP=*/false,
- *image_it, nullptr, nullptr, nullptr),
- AVIF_APP_FILE_FORMAT_UNKNOWN);
- ++image_it;
- }
-
- for (avifImage* image : images) {
- EXPECT_TRUE(testutil::AreByteSequencesEqual(image->exif, images[0]->exif));
- EXPECT_TRUE(testutil::AreByteSequencesEqual(image->xmp, images[0]->xmp));
- EXPECT_TRUE(testutil::AreByteSequencesEqual(image->icc, images[0]->icc));
+ for (const char* file_name :
+ {"paris_exif_xmp_icc.jpg", "paris_icc_exif_xmp_at_end.png"}) {
+ const testutil::AvifImagePtr image =
+ testutil::ReadImage(data_path, file_name);
+ ASSERT_NE(image, nullptr);
+ EXPECT_TRUE(testutil::AreByteSequencesEqual(image->exif, ref->exif));
+ EXPECT_TRUE(testutil::AreByteSequencesEqual(image->xmp, ref->xmp));
+ EXPECT_TRUE(testutil::AreByteSequencesEqual(image->icc, ref->icc));
}
}
diff --git a/tests/gtest/aviftest_helpers.cc b/tests/gtest/aviftest_helpers.cc
index 493512a..25827b6 100644
--- a/tests/gtest/aviftest_helpers.cc
+++ b/tests/gtest/aviftest_helpers.cc
@@ -6,8 +6,10 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
+#include <string>
#include "avif/avif.h"
+#include "avifutil.h"
namespace libavif {
namespace testutil {
@@ -227,6 +229,26 @@
AreByteSequencesEqual(image1.xmp, image2.xmp);
}
+//------------------------------------------------------------------------------
+
+AvifImagePtr ReadImage(const char* folder_path, const char* file_name,
+ avifPixelFormat requested_format, int requested_depth,
+ avifRGBToYUVFlags flags, avifBool ignore_icc,
+ avifBool ignore_exif, avifBool ignore_xmp) {
+ testutil::AvifImagePtr image(avifImageCreateEmpty(), avifImageDestroy);
+ if (!image ||
+ avifReadImage((std::string(folder_path) + file_name).c_str(),
+ requested_format, requested_depth, flags, ignore_icc,
+ ignore_exif, ignore_xmp, image.get(), /*outDepth=*/nullptr,
+ /*sourceTiming=*/nullptr,
+ /*frameIter=*/nullptr) == AVIF_APP_FILE_FORMAT_UNKNOWN) {
+ return {nullptr, avifImageDestroy};
+ }
+ return image;
+}
+
+//------------------------------------------------------------------------------
+
static avifResult avifIOLimitedReaderRead(avifIO* io, uint32_t readFlags,
uint64_t offset, size_t size,
avifROData* out) {
@@ -264,5 +286,6 @@
}
//------------------------------------------------------------------------------
+
} // namespace testutil
} // namespace libavif
diff --git a/tests/gtest/aviftest_helpers.h b/tests/gtest/aviftest_helpers.h
index f7f2a2c..842b60d 100644
--- a/tests/gtest/aviftest_helpers.h
+++ b/tests/gtest/aviftest_helpers.h
@@ -68,6 +68,18 @@
bool ignore_alpha = false);
//------------------------------------------------------------------------------
+// Shorter versions of avifutil.h functions
+
+// Reads the image named file_name located in directory at folder_path.
+// Returns nullptr in case of error.
+AvifImagePtr ReadImage(
+ const char* folder_path, const char* file_name,
+ avifPixelFormat requested_format = AVIF_PIXEL_FORMAT_NONE,
+ int requested_depth = 0, avifRGBToYUVFlags flags = AVIF_RGB_TO_YUV_DEFAULT,
+ avifBool ignore_icc = false, avifBool ignore_exif = false,
+ avifBool ignore_xmp = false);
+
+//------------------------------------------------------------------------------
// avifIO overlay
struct AvifIOLimitedReader {