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

#include "convert_command.h"

#include "avif/avif_cxx.h"
#include "avifutil.h"
#include "imageio.h"
#include "swapbase_command.h"

namespace avif {

ConvertCommand::ConvertCommand()
    : ProgramCommand("convert", "Convert a JPEG with a gain map to AVIF",
                     "If features like --swap-base are not needed, avifenc can "
                     "also be used to convert JPEGs to AVIF.") {
  argparse_.add_argument(arg_input_filename_, "input_filename.jpg");
  argparse_.add_argument(arg_output_filename_, "output_image.avif");
  argparse_.add_argument(arg_swap_base_, "--swap-base")
      .help("Make the HDR image the base image")
      .action(argparse::Action::STORE_TRUE)
      .default_value("false");
  argparse_.add_argument(arg_gain_map_quality_, "--qgain-map")
      .help("Quality for the gain map (0-100, where 100 is lossless)")
      .default_value("60");
  argparse_.add_argument<CicpValues, CicpConverter>(arg_cicp_, "--cicp")
      .help(
          "Set the CICP values for the input image, expressed as "
          "P/T/M where P = color primaries, T = transfer characteristics, "
          "M = matrix coefficients.");
  argparse_
      .add_argument<avifContentLightLevelInformationBox, ClliConverter>(
          arg_clli_, "--clli")
      .help(
          "Set the content light level information of the alternate image, "
          "expressed as:  MaxCLL,MaxPALL.");
  arg_image_encode_.Init(argparse_, /*can_have_alpha=*/false);
  arg_image_read_.Init(argparse_);
  arg_jobs_.Init(argparse_);
}

avifResult ConvertCommand::Run() {
#if !defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
  std::cout << "JPEG gainmap conversion unavailable because avifgainmaputil "
               "was not built with libxml2.\n";
  return AVIF_RESULT_NOT_IMPLEMENTED;
#else
  const avifPixelFormat pixel_format =
      static_cast<avifPixelFormat>(arg_image_read_.pixel_format.value());

  ImagePtr image(avifImageCreateEmpty());
  if (image == nullptr) {
    return AVIF_RESULT_OUT_OF_MEMORY;
  }

  if (arg_cicp_.provenance() == argparse::Provenance::SPECIFIED) {
    image->colorPrimaries = arg_cicp_.value().color_primaries;
    image->transferCharacteristics = arg_cicp_.value().transfer_characteristics;
    image->matrixCoefficients = arg_cicp_.value().matrix_coefficients;
  }

  avifResult result =
      ReadImage(image.get(), arg_input_filename_.value(), pixel_format,
                arg_image_read_.depth, arg_image_read_.ignore_profile,
                /*ignore_gain_map=*/false, arg_jobs_.jobs.value());
  if (result != AVIF_RESULT_OK) {
    std::cout << "Failed to decode image: " << arg_input_filename_;
    return result;
  }

  if (image->gainMap && image->gainMap->altICC.size == 0) {
    if (image->gainMap->altColorPrimaries == AVIF_COLOR_PRIMARIES_UNSPECIFIED) {
      // Assume the alternate image has the same primaries as the base image.
      image->gainMap->altColorPrimaries = image->colorPrimaries;
    }
    if (image->gainMap->altTransferCharacteristics ==
        AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED) {
      // Assume the alternate image is PQ HDR.
      image->gainMap->altTransferCharacteristics =
          AVIF_TRANSFER_CHARACTERISTICS_PQ;
    }
  }

  if (image->gainMap == nullptr || image->gainMap->image == nullptr) {
    std::cerr << "Input image " << arg_input_filename_
              << " does not contain a gain map\n";
    return AVIF_RESULT_INVALID_ARGUMENT;
  }

  image->gainMap->altCLLI = arg_clli_.value();

  if (arg_swap_base_) {
    int depth = arg_image_read_.depth;
    if (depth == 0) {
      depth = image->gainMap->alternateHdrHeadroom.n == 0 ? 8 : 10;
    }
    ImagePtr new_base(avifImageCreateEmpty());
    if (new_base == nullptr) {
      return AVIF_RESULT_OUT_OF_MEMORY;
    }
    result = ChangeBase(*image, depth, image->yuvFormat, new_base.get());
    if (result != AVIF_RESULT_OK) {
      return result;
    }
    std::swap(image, new_base);
  }

  EncoderPtr encoder(avifEncoderCreate());
  if (encoder == nullptr) {
    return AVIF_RESULT_OUT_OF_MEMORY;
  }
  encoder->quality = arg_image_encode_.quality;
  encoder->qualityAlpha = arg_image_encode_.quality_alpha;
  encoder->qualityGainMap = arg_gain_map_quality_;
  encoder->speed = arg_image_encode_.speed;
  encoder->maxThreads = arg_jobs_.jobs.value();
  encoder->autoTiling = true;  // Match avifenc default.
  result = WriteAvifGrid(image.get(), arg_image_encode_.grid.value().grid_cols,
                         arg_image_encode_.grid.value().grid_rows,
                         encoder.get(), arg_output_filename_);
  if (result != AVIF_RESULT_OK) {
    std::cout << "Failed to encode image: " << avifResultToString(result)
              << " (" << encoder->diag.error << ")\n";
    return result;
  }

  return AVIF_RESULT_OK;
#endif  // !defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
}

}  // namespace avif
