1 // Copyright 2024 Google LLC
2 // SPDX-License-Identifier: BSD-2-Clause
3 
4 #include <cstring>
5 #include <iostream>
6 #include <string>
7 
8 #include "avif/avif.h"
9 #include "aviftest_helpers.h"
10 #include "gtest/gtest.h"
11 
12 namespace avif {
13 namespace {
14 
15 // Used to pass the data folder path to the GoogleTest suites.
16 const char* data_path = nullptr;
17 
18 class ImageTest : public testing::TestWithParam<const char*> {};
19 
TEST_P(ImageTest,ImageCopy)20 TEST_P(ImageTest, ImageCopy) {
21   if (!testutil::Av1DecoderAvailable()) {
22     GTEST_SKIP() << "AV1 Codec unavailable, skip test.";
23   }
24   const char* file_name = GetParam();
25   DecoderPtr decoder(avifDecoderCreate());
26   ASSERT_NE(decoder, nullptr);
27   ASSERT_EQ(avifDecoderSetIOFile(decoder.get(),
28                                  (std::string(data_path) + file_name).c_str()),
29             AVIF_RESULT_OK);
30   ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK);
31   EXPECT_EQ(decoder->compressionFormat, COMPRESSION_FORMAT_AVIF);
32   EXPECT_EQ(avifDecoderNextImage(decoder.get()), AVIF_RESULT_OK);
33 
34   ImagePtr image2(avifImageCreateEmpty());
35   ASSERT_EQ(avifImageCopy(image2.get(), decoder->image, AVIF_PLANES_ALL),
36             AVIF_RESULT_OK);
37   EXPECT_EQ(decoder->image->width, image2->width);
38   EXPECT_EQ(decoder->image->height, image2->height);
39   EXPECT_EQ(decoder->image->depth, image2->depth);
40   EXPECT_EQ(decoder->image->yuvFormat, image2->yuvFormat);
41   EXPECT_EQ(decoder->image->yuvRange, image2->yuvRange);
42   for (int plane = 0; plane < 3; ++plane) {
43     EXPECT_EQ(decoder->image->yuvPlanes[plane] == nullptr,
44               image2->yuvPlanes[plane] == nullptr);
45     if (decoder->image->yuvPlanes[plane] == nullptr) continue;
46     EXPECT_EQ(decoder->image->yuvRowBytes[plane], image2->yuvRowBytes[plane]);
47     EXPECT_NE(decoder->image->yuvPlanes[plane], image2->yuvPlanes[plane]);
48     const auto plane_height = avifImagePlaneHeight(decoder->image, plane);
49     const auto plane_size = plane_height * decoder->image->yuvRowBytes[plane];
50     EXPECT_EQ(memcmp(decoder->image->yuvPlanes[plane], image2->yuvPlanes[plane],
51                      plane_size),
52               0);
53   }
54   EXPECT_EQ(decoder->image->alphaPlane == nullptr,
55             image2->alphaPlane == nullptr);
56   if (decoder->image->alphaPlane != nullptr) {
57     EXPECT_EQ(decoder->image->alphaRowBytes, image2->alphaRowBytes);
58     EXPECT_NE(decoder->image->alphaPlane, image2->alphaPlane);
59     const auto plane_size =
60         decoder->image->height * decoder->image->alphaRowBytes;
61     EXPECT_EQ(
62         memcmp(decoder->image->alphaPlane, image2->alphaPlane, plane_size), 0);
63   }
64 }
65 
66 INSTANTIATE_TEST_SUITE_P(Some, ImageTest,
67                          testing::ValuesIn({"paris_10bpc.avif", "alpha.avif",
68                                             "colors-animated-8bpc.avif"}));
69 
70 }  // namespace
71 }  // namespace avif
72 
main(int argc,char ** argv)73 int main(int argc, char** argv) {
74   ::testing::InitGoogleTest(&argc, argv);
75   if (argc != 2) {
76     std::cerr << "There must be exactly one argument containing the path to "
77                  "the test data folder"
78               << std::endl;
79     return 1;
80   }
81   avif::data_path = argv[1];
82   return RUN_ALL_TESTS();
83 }
84