1 // Copyright 2023 Google LLC
2 // SPDX-License-Identifier: BSD-2-Clause
3
4 #include "avif/avif.h"
5 #include "aviftest_helpers.h"
6 #include "gtest/gtest.h"
7
8 namespace avif {
9 namespace {
10
11 // Used to pass the data folder path to the GoogleTest suites.
12 const char* data_path = nullptr;
13
get_file_name(const char * file_name)14 std::string get_file_name(const char* file_name) {
15 return std::string(data_path) + file_name;
16 }
17
TEST(AvifDecodeTest,OneShotDecodeFile)18 TEST(AvifDecodeTest, OneShotDecodeFile) {
19 if (!testutil::Av1DecoderAvailable()) {
20 GTEST_SKIP() << "AV1 Codec unavailable, skip test.";
21 }
22 const char* file_name = "sofa_grid1x5_420.avif";
23 DecoderPtr decoder(avifDecoderCreate());
24 ASSERT_NE(decoder, nullptr);
25 avifImage image;
26 ASSERT_EQ(avifDecoderReadFile(decoder.get(), &image,
27 get_file_name(file_name).c_str()),
28 AVIF_RESULT_OK);
29 EXPECT_EQ(image.width, 1024);
30 EXPECT_EQ(image.height, 770);
31 EXPECT_EQ(image.depth, 8);
32
33 // Call avifDecoderReadFile with a different file but with the same decoder
34 // instance.
35 file_name = "white_1x1.avif";
36 ASSERT_EQ(avifDecoderReadFile(decoder.get(), &image,
37 get_file_name(file_name).c_str()),
38 AVIF_RESULT_OK);
39 EXPECT_EQ(image.width, 1);
40 EXPECT_EQ(image.height, 1);
41 EXPECT_EQ(image.depth, 8);
42 }
43
TEST(AvifDecodeTest,OneShotDecodeMemory)44 TEST(AvifDecodeTest, OneShotDecodeMemory) {
45 if (!testutil::Av1DecoderAvailable()) {
46 GTEST_SKIP() << "AV1 Codec unavailable, skip test.";
47 }
48 const char* file_name = "sofa_grid1x5_420.avif";
49 auto file_data = testutil::read_file(get_file_name(file_name).c_str());
50 DecoderPtr decoder(avifDecoderCreate());
51 ASSERT_NE(decoder, nullptr);
52 avifImage image;
53 ASSERT_EQ(avifDecoderReadMemory(decoder.get(), &image, file_data.data(),
54 file_data.size()),
55 AVIF_RESULT_OK);
56 EXPECT_EQ(image.width, 1024);
57 EXPECT_EQ(image.height, 770);
58 EXPECT_EQ(image.depth, 8);
59 }
60
io_read(struct avifIO * io,uint32_t flags,uint64_t offset,size_t size,avifROData * out)61 avifResult io_read(struct avifIO* io, uint32_t flags, uint64_t offset,
62 size_t size, avifROData* out) {
63 avifROData* src = (avifROData*)io->data;
64 if (flags != 0 || offset > src->size) {
65 return AVIF_RESULT_IO_ERROR;
66 }
67 uint64_t available_size = src->size - offset;
68 if (size > available_size) {
69 size = static_cast<size_t>(available_size);
70 }
71 out->data = src->data + offset;
72 out->size = size;
73 return AVIF_RESULT_OK;
74 }
75
TEST(AvifDecodeTest,OneShotDecodeCustomIO)76 TEST(AvifDecodeTest, OneShotDecodeCustomIO) {
77 if (!testutil::Av1DecoderAvailable()) {
78 GTEST_SKIP() << "AV1 Codec unavailable, skip test.";
79 }
80 const char* file_name = "sofa_grid1x5_420.avif";
81 auto data = testutil::read_file(get_file_name(file_name).c_str());
82 avifROData ro_data = {.data = data.data(), .size = data.size()};
83 avifIO io = {.destroy = nullptr,
84 .read = io_read,
85 .sizeHint = data.size(),
86 .persistent = false,
87 .data = static_cast<void*>(&ro_data)};
88 DecoderPtr decoder(avifDecoderCreate());
89 ASSERT_NE(decoder, nullptr);
90 avifDecoderSetIO(decoder.get(), &io);
91 avifImage image;
92 ASSERT_EQ(avifDecoderRead(decoder.get(), &image), AVIF_RESULT_OK);
93 EXPECT_EQ(image.width, 1024);
94 EXPECT_EQ(image.height, 770);
95 EXPECT_EQ(image.depth, 8);
96 }
97
TEST(AvifDecodeTest,NthImage)98 TEST(AvifDecodeTest, NthImage) {
99 if (!testutil::Av1DecoderAvailable()) {
100 GTEST_SKIP() << "AV1 Codec unavailable, skip test.";
101 }
102 const char* file_name = "colors-animated-8bpc.avif";
103 DecoderPtr decoder(avifDecoderCreate());
104 ASSERT_NE(decoder, nullptr);
105 ASSERT_EQ(avifDecoderSetIOFile(decoder.get(),
106 (std::string(data_path) + file_name).c_str()),
107 AVIF_RESULT_OK);
108 ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK);
109 EXPECT_EQ(decoder->compressionFormat, COMPRESSION_FORMAT_AVIF);
110 EXPECT_EQ(decoder->imageCount, 5);
111 EXPECT_EQ(avifDecoderNthImage(decoder.get(), 3), AVIF_RESULT_OK);
112 EXPECT_EQ(avifDecoderNextImage(decoder.get()), AVIF_RESULT_OK);
113 EXPECT_NE(avifDecoderNextImage(decoder.get()), AVIF_RESULT_OK);
114 EXPECT_EQ(avifDecoderNthImage(decoder.get(), 1), AVIF_RESULT_OK);
115 EXPECT_EQ(avifDecoderNthImage(decoder.get(), 4), AVIF_RESULT_OK);
116 EXPECT_NE(avifDecoderNthImage(decoder.get(), 50), AVIF_RESULT_OK);
117 for (int i = 0; i < 5; ++i) {
118 }
119 }
120
121 } // namespace
122 } // namespace avif
123
main(int argc,char ** argv)124 int main(int argc, char** argv) {
125 ::testing::InitGoogleTest(&argc, argv);
126 if (argc != 2) {
127 std::cerr << "There must be exactly one argument containing the path to "
128 "the test data folder"
129 << std::endl;
130 return 1;
131 }
132 avif::data_path = argv[1];
133 return RUN_ALL_TESTS();
134 }
135