// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/avif.h"
#include "aviftest_helpers.h"
#include "avifutil.h"
#include "gtest/gtest.h"

namespace avif {
namespace {

// Used to pass the data folder path to the GoogleTest suites.
const char* data_path = nullptr;

// Tests encode/decode round trips under different matrix coefficients.
TEST(BasicTest, EncodeDecodeMatrixCoefficients) {
  for (const auto& file_name :
       {"paris_icc_exif_xmp.png", "paris_exif_xmp_icc.jpg"}) {
    // Read a ground truth image with default matrix coefficients.
    const std::string file_path = std::string(data_path) + file_name;
    const ImagePtr ground_truth_image =
        testutil::ReadImage(data_path, file_name);

    for (auto matrix_coefficient :
         {AVIF_MATRIX_COEFFICIENTS_IDENTITY, AVIF_MATRIX_COEFFICIENTS_YCGCO,
          AVIF_MATRIX_COEFFICIENTS_YCGCO_RE,
          AVIF_MATRIX_COEFFICIENTS_YCGCO_RO}) {
      // Read a ground truth image but ask for certain matrix coefficients.
      ImagePtr image(avifImageCreateEmpty());
      ASSERT_NE(image, nullptr);
      image->matrixCoefficients = (avifMatrixCoefficients)matrix_coefficient;
      const avifAppFileFormat file_format = avifReadImage(
          file_path.c_str(),
          /*requestedFormat=*/AVIF_PIXEL_FORMAT_NONE,
          /*requestedDepth=*/0,
          /*chromaDownsampling=*/AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC,
          /*ignoreColorProfile=*/false, /*ignoreExif=*/false,
          /*ignoreXMP=*/false, /*allowChangingCicp=*/true,
          /*ignoreGainMap=*/true, AVIF_DEFAULT_IMAGE_SIZE_LIMIT, image.get(),
          /*outDepth=*/nullptr, /*sourceTiming=*/nullptr,
          /*frameIter=*/nullptr);
      if (matrix_coefficient == AVIF_MATRIX_COEFFICIENTS_YCGCO_RO) {
        // AVIF_MATRIX_COEFFICIENTS_YCGCO_RO does not work because the input
        // depth is not odd.
        ASSERT_EQ(file_format, AVIF_APP_FILE_FORMAT_UNKNOWN);
        continue;
      }
      ASSERT_NE(file_format, AVIF_APP_FILE_FORMAT_UNKNOWN);

      // Encode.
      EncoderPtr encoder(avifEncoderCreate());
      ASSERT_NE(encoder, nullptr);
      encoder->speed = AVIF_SPEED_FASTEST;
      encoder->quality = AVIF_QUALITY_LOSSLESS;
      encoder->qualityAlpha = AVIF_QUALITY_LOSSLESS;
      testutil::AvifRwData encoded;
      avifResult result =
          avifEncoderWrite(encoder.get(), image.get(), &encoded);
      ASSERT_EQ(result, AVIF_RESULT_OK) << avifResultToString(result);

      // Decode to RAM.
      ImagePtr decoded(avifImageCreateEmpty());
      ASSERT_NE(decoded, nullptr);
      DecoderPtr decoder(avifDecoderCreate());
      ASSERT_NE(decoder, nullptr);
      result = avifDecoderReadMemory(decoder.get(), decoded.get(), encoded.data,
                                     encoded.size);
      ASSERT_EQ(result, AVIF_RESULT_OK) << avifResultToString(result);

      // Convert to a temporary PNG and read back, to have default matrix
      // coefficients.
      const std::string temp_dir = testing::TempDir();
      const std::string temp_file = "decoded_default.png";
      const std::string tmp_path = temp_dir + temp_file;
      ASSERT_TRUE(testutil::WriteImage(decoded.get(), tmp_path.c_str()));
      const ImagePtr decoded_default =
          testutil::ReadImage(temp_dir.c_str(), temp_file.c_str());

      // Verify that the ground truth and decoded images are the same.
      const bool are_images_equal =
          testutil::AreImagesEqual(*ground_truth_image, *decoded_default);

      if (matrix_coefficient == AVIF_MATRIX_COEFFICIENTS_IDENTITY ||
          matrix_coefficient == AVIF_MATRIX_COEFFICIENTS_YCGCO_RE) {
        ASSERT_TRUE(are_images_equal);
      } else {
        // AVIF_MATRIX_COEFFICIENTS_YCGCO is not lossless because it does not
        // expand the input bit range for YCgCo values.
        ASSERT_FALSE(are_images_equal);
      }
    }
  }
}

}  // namespace
}  // namespace avif

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  if (argc != 2) {
    std::cerr << "There must be exactly one argument containing the path to "
                 "the test data folder"
              << std::endl;
    return 1;
  }
  avif::data_path = argv[1];
  return RUN_ALL_TESTS();
}
