// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
//
// Tests the jpeg/png/y4m reading code from avifenc.

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

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

using ::fuzztest::Arbitrary;
using ::fuzztest::ElementOf;

namespace avif {
namespace testutil {
namespace {

::testing::Environment* const kStackLimitEnv = SetStackLimitTo512x1024Bytes();

//------------------------------------------------------------------------------

std::string FileFormatToString(avifAppFileFormat file_format) {
  switch (file_format) {
    case AVIF_APP_FILE_FORMAT_PNG:
      return "PNG";
    case AVIF_APP_FILE_FORMAT_JPEG:
      return "JPEG";
    case AVIF_APP_FILE_FORMAT_Y4M:
      return "Y4M";
    default:
      assert(false);
      return "unknown";
  }
}

void ReadImageFile(const std::string& arbitrary_bytes,
                   avifPixelFormat requested_format, int requested_depth,
                   avifChromaDownsampling chroma_downsampling,
                   bool ignore_color_profile, bool ignore_exif, bool ignore_xmp,
                   bool allow_changing_cicp, bool ignore_gain_map,
                   avifMatrixCoefficients matrix_coefficients) {
  ASSERT_FALSE(GetSeedDataDirs().empty());  // Make sure seeds are available.

  // Write the byte stream to a temp file since avifReadImage() takes a file
  // path as input.
  const std::string file_path = testing::TempDir() + "inputimage";
  std::ofstream out(file_path);
  out << arbitrary_bytes;
  out.close();

  uint32_t out_depth;
  avifAppSourceTiming timing;
  ImagePtr avif_image(avifImageCreateEmpty());
  avif_image->matrixCoefficients = matrix_coefficients;

  // OSS-Fuzz limits the allocated memory to 2560 MB.
  constexpr uint32_t kMaxMem = 2560u * 1024 * 1024;
  // Consider at most four planes of 16-bit samples.
  constexpr uint32_t kMaxImageSize =
      kMaxMem / (AVIF_PLANE_COUNT_YUV + 1) / sizeof(uint16_t);
  // Reduce the limit further to include pixel buffer copies and other memory
  // allocations.
  constexpr uint32_t kImageSizeLimit = kMaxImageSize / 4;
  // SharpYUV is computationally expensive. Avoid timeouts.
  const uint32_t imageSizeLimit =
      (chroma_downsampling == AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV &&
       requested_format == AVIF_PIXEL_FORMAT_YUV420)
          ? kImageSizeLimit / 8
          : kImageSizeLimit;

  const avifAppFileFormat file_format = avifReadImage(
      file_path.c_str(), requested_format, requested_depth, chroma_downsampling,
      ignore_color_profile, ignore_exif, ignore_xmp, allow_changing_cicp,
      ignore_gain_map, imageSizeLimit, avif_image.get(), &out_depth, &timing,
      /*frameIter=*/nullptr);

  if (file_format != AVIF_APP_FILE_FORMAT_UNKNOWN) {
    EXPECT_GT(avif_image->width, 0);
    EXPECT_GT(avif_image->height, 0);

    if (requested_depth != 0 && file_format != AVIF_APP_FILE_FORMAT_Y4M) {
      EXPECT_EQ(avif_image->depth, requested_depth);
    }
    if (file_format != AVIF_APP_FILE_FORMAT_Y4M) {
      EXPECT_EQ(avif_image->yuvFormat, requested_format);
    }
    if (ignore_color_profile) {
      EXPECT_EQ(avif_image->icc.size, 0);
    }
    if (ignore_exif) {
      EXPECT_EQ(avif_image->exif.size, 0);
    }
    if (ignore_xmp) {
      EXPECT_EQ(avif_image->xmp.size, 0);
    }
    std::cout << "Decode successful (" << FileFormatToString(file_format)
              << ")\n";
  }
}

FUZZ_TEST(ReadImageFuzzTest, ReadImageFile)
    .WithDomains(ArbitraryImageWithSeeds({AVIF_APP_FILE_FORMAT_JPEG,
                                          AVIF_APP_FILE_FORMAT_PNG,
                                          AVIF_APP_FILE_FORMAT_Y4M}),
                 ArbitraryPixelFormat(),
                 /*requested_depth=*/ElementOf({0, 8, 10, 12}),
                 ElementOf({AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC,
                            AVIF_CHROMA_DOWNSAMPLING_FASTEST,
                            AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY,
                            AVIF_CHROMA_DOWNSAMPLING_AVERAGE,
                            AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV}),
                 /*ignore_color_profile=*/Arbitrary<bool>(),
                 /*ignore_exif=*/Arbitrary<bool>(),
                 /*ignore_xmp=*/Arbitrary<bool>(),
                 /*allow_changing_cicp=*/Arbitrary<bool>(),
                 /*ignore_gain_map=*/Arbitrary<bool>(),
                 ElementOf({AVIF_MATRIX_COEFFICIENTS_IDENTITY,
                            AVIF_MATRIX_COEFFICIENTS_BT709,
                            AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED,
                            AVIF_MATRIX_COEFFICIENTS_FCC,
                            AVIF_MATRIX_COEFFICIENTS_BT470BG,
                            AVIF_MATRIX_COEFFICIENTS_BT601,
                            AVIF_MATRIX_COEFFICIENTS_SMPTE240,
                            AVIF_MATRIX_COEFFICIENTS_YCGCO,
                            AVIF_MATRIX_COEFFICIENTS_BT2020_NCL,
                            AVIF_MATRIX_COEFFICIENTS_BT2020_CL,
                            AVIF_MATRIX_COEFFICIENTS_SMPTE2085,
                            AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL,
                            AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL,
                            AVIF_MATRIX_COEFFICIENTS_ICTCP}));

//------------------------------------------------------------------------------

}  // namespace
}  // namespace testutil
}  // namespace avif
