/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

/*!\file
 * \brief This file has the implementation details of the grain table.
 *
 * The file format is an ascii representation for readability and
 * editability. Array parameters are separated from the non-array
 * parameters and prefixed with a few characters to make for easy
 * localization with a parameter set. Each entry is prefixed with "E"
 * and the other parameters are only specified if "update-parms" is
 * non-zero.
 *
 * filmgrn1
 * E <start-time> <end-time> <apply-grain> <random-seed> <update-parms>
 *  p <ar_coeff_lag> <ar_coeff_shift> <grain_scale_shift> ...
 *  sY <num_y_points> <point_0_x> <point_0_y> ...
 *  sCb <num_cb_points> <point_0_x> <point_0_y> ...
 *  sCr <num_cr_points> <point_0_x> <point_0_y> ...
 *  cY <ar_coeff_y_0> ....
 *  cCb <ar_coeff_cb_0> ....
 *  cCr <ar_coeff_cr_0> ....
 * E <start-time> ...
 */
#include <string.h>
#include <stdio.h>
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/grain_table.h"
#include "aom_mem/aom_mem.h"

static const char kFileMagic[8] = "filmgrn1";

static void grain_table_entry_read(FILE *file,
                                   struct aom_internal_error_info *error_info,
                                   aom_film_grain_table_entry_t *entry) {
  aom_film_grain_t *pars = &entry->params;
  int num_read =
      fscanf(file, "E %" PRId64 " %" PRId64 " %d %hd %d\n", &entry->start_time,
             &entry->end_time, &pars->apply_grain, &pars->random_seed,
             &pars->update_parameters);
  if (num_read == 0 && feof(file)) return;
  if (num_read != 5) {
    aom_internal_error(error_info, AOM_CODEC_ERROR,
                       "Unable to read entry header. Read %d != 5", num_read);
    return;
  }
  if (pars->update_parameters) {
    num_read = fscanf(file, "p %d %d %d %d %d %d %d %d %d %d %d %d\n",
                      &pars->ar_coeff_lag, &pars->ar_coeff_shift,
                      &pars->grain_scale_shift, &pars->scaling_shift,
                      &pars->chroma_scaling_from_luma, &pars->overlap_flag,
                      &pars->cb_mult, &pars->cb_luma_mult, &pars->cb_offset,
                      &pars->cr_mult, &pars->cr_luma_mult, &pars->cr_offset);
    if (num_read != 12) {
      aom_internal_error(error_info, AOM_CODEC_ERROR,
                         "Unable to read entry params. Read %d != 12",
                         num_read);
      return;
    }
    if (!fscanf(file, "\tsY %d ", &pars->num_y_points)) {
      aom_internal_error(error_info, AOM_CODEC_ERROR,
                         "Unable to read num y points");
      return;
    }
    for (int i = 0; i < pars->num_y_points; ++i) {
      if (2 != fscanf(file, "%d %d", &pars->scaling_points_y[i][0],
                      &pars->scaling_points_y[i][1])) {
        aom_internal_error(error_info, AOM_CODEC_ERROR,
                           "Unable to read y scaling points");
        return;
      }
    }
    if (!fscanf(file, "\n\tsCb %d", &pars->num_cb_points)) {
      aom_internal_error(error_info, AOM_CODEC_ERROR,
                         "Unable to read num cb points");
      return;
    }
    for (int i = 0; i < pars->num_cb_points; ++i) {
      if (2 != fscanf(file, "%d %d", &pars->scaling_points_cb[i][0],
                      &pars->scaling_points_cb[i][1])) {
        aom_internal_error(error_info, AOM_CODEC_ERROR,
                           "Unable to read cb scaling points");
        return;
      }
    }
    if (!fscanf(file, "\n\tsCr %d", &pars->num_cr_points)) {
      aom_internal_error(error_info, AOM_CODEC_ERROR,
                         "Unable to read num cr points");
      return;
    }
    for (int i = 0; i < pars->num_cr_points; ++i) {
      if (2 != fscanf(file, "%d %d", &pars->scaling_points_cr[i][0],
                      &pars->scaling_points_cr[i][1])) {
        aom_internal_error(error_info, AOM_CODEC_ERROR,
                           "Unable to read cr scaling points");
        return;
      }
    }

    if (fscanf(file, "\n\tcY")) {
      aom_internal_error(error_info, AOM_CODEC_ERROR,
                         "Unable to read Y coeffs header (cY)");
      return;
    }
    const int n = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1);
    for (int i = 0; i < n; ++i) {
      if (1 != fscanf(file, "%d", &pars->ar_coeffs_y[i])) {
        aom_internal_error(error_info, AOM_CODEC_ERROR,
                           "Unable to read Y coeffs");
        return;
      }
    }
    if (fscanf(file, "\n\tcCb")) {
      aom_internal_error(error_info, AOM_CODEC_ERROR,
                         "Unable to read Cb coeffs header (cCb)");
      return;
    }
    for (int i = 0; i <= n; ++i) {
      if (1 != fscanf(file, "%d", &pars->ar_coeffs_cb[i])) {
        aom_internal_error(error_info, AOM_CODEC_ERROR,
                           "Unable to read Cb coeffs");
        return;
      }
    }
    if (fscanf(file, "\n\tcCr")) {
      aom_internal_error(error_info, AOM_CODEC_ERROR,
                         "Unable read to Cr coeffs header (cCr)");
      return;
    }
    for (int i = 0; i <= n; ++i) {
      if (1 != fscanf(file, "%d", &pars->ar_coeffs_cr[i])) {
        aom_internal_error(error_info, AOM_CODEC_ERROR,
                           "Unable to read Cr coeffs");
        return;
      }
    }
    (void)fscanf(file, "\n");
  }
}

static void grain_table_entry_write(FILE *file,
                                    aom_film_grain_table_entry_t *entry) {
  const aom_film_grain_t *pars = &entry->params;
  fprintf(file, "E %" PRId64 " %" PRId64 " %d %d %d\n", entry->start_time,
          entry->end_time, pars->apply_grain, pars->random_seed,
          pars->update_parameters);
  if (pars->update_parameters) {
    fprintf(file, "\tp %d %d %d %d %d %d %d %d %d %d %d %d\n",
            pars->ar_coeff_lag, pars->ar_coeff_shift, pars->grain_scale_shift,
            pars->scaling_shift, pars->chroma_scaling_from_luma,
            pars->overlap_flag, pars->cb_mult, pars->cb_luma_mult,
            pars->cb_offset, pars->cr_mult, pars->cr_luma_mult,
            pars->cr_offset);
    fprintf(file, "\tsY %d ", pars->num_y_points);
    for (int i = 0; i < pars->num_y_points; ++i) {
      fprintf(file, " %d %d", pars->scaling_points_y[i][0],
              pars->scaling_points_y[i][1]);
    }
    fprintf(file, "\n\tsCb %d", pars->num_cb_points);
    for (int i = 0; i < pars->num_cb_points; ++i) {
      fprintf(file, " %d %d", pars->scaling_points_cb[i][0],
              pars->scaling_points_cb[i][1]);
    }
    fprintf(file, "\n\tsCr %d", pars->num_cr_points);
    for (int i = 0; i < pars->num_cr_points; ++i) {
      fprintf(file, " %d %d", pars->scaling_points_cr[i][0],
              pars->scaling_points_cr[i][1]);
    }
    fprintf(file, "\n\tcY");
    const int n = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1);
    for (int i = 0; i < n; ++i) {
      fprintf(file, " %d", pars->ar_coeffs_y[i]);
    }
    fprintf(file, "\n\tcCb");
    for (int i = 0; i <= n; ++i) {
      fprintf(file, " %d", pars->ar_coeffs_cb[i]);
    }
    fprintf(file, "\n\tcCr");
    for (int i = 0; i <= n; ++i) {
      fprintf(file, " %d", pars->ar_coeffs_cr[i]);
    }
    fprintf(file, "\n");
  }
}

// TODO(https://crbug.com/aomedia/3228): Update this function to return an
// integer status.
void aom_film_grain_table_append(aom_film_grain_table_t *t, int64_t time_stamp,
                                 int64_t end_time,
                                 const aom_film_grain_t *grain) {
  if (!t->tail || memcmp(grain, &t->tail->params, sizeof(*grain))) {
    aom_film_grain_table_entry_t *new_tail = aom_malloc(sizeof(*new_tail));
    if (!new_tail) return;
    memset(new_tail, 0, sizeof(*new_tail));
    if (t->tail) t->tail->next = new_tail;
    if (!t->head) t->head = new_tail;
    t->tail = new_tail;

    new_tail->start_time = time_stamp;
    new_tail->end_time = end_time;
    new_tail->params = *grain;
  } else {
    t->tail->end_time = AOMMAX(t->tail->end_time, end_time);
    t->tail->start_time = AOMMIN(t->tail->start_time, time_stamp);
  }
}

int aom_film_grain_table_lookup(aom_film_grain_table_t *t, int64_t time_stamp,
                                int64_t end_time, int erase,
                                aom_film_grain_t *grain) {
  aom_film_grain_table_entry_t *entry = t->head;
  aom_film_grain_table_entry_t *prev_entry = NULL;
  uint16_t random_seed = grain ? grain->random_seed : 0;
  if (grain) memset(grain, 0, sizeof(*grain));

  while (entry) {
    aom_film_grain_table_entry_t *next = entry->next;
    if (time_stamp >= entry->start_time && time_stamp < entry->end_time) {
      if (grain) {
        *grain = entry->params;
        if (time_stamp != 0) grain->random_seed = random_seed;
      }
      if (!erase) return 1;

      const int64_t entry_end_time = entry->end_time;
      if (time_stamp <= entry->start_time && end_time >= entry->end_time) {
        if (t->tail == entry) t->tail = prev_entry;
        if (prev_entry) {
          prev_entry->next = entry->next;
        } else {
          t->head = entry->next;
        }
        aom_free(entry);
      } else if (time_stamp <= entry->start_time &&
                 end_time < entry->end_time) {
        entry->start_time = end_time;
      } else if (time_stamp > entry->start_time &&
                 end_time >= entry->end_time) {
        entry->end_time = time_stamp;
      } else {
        aom_film_grain_table_entry_t *new_entry =
            aom_malloc(sizeof(*new_entry));
        if (!new_entry) return 0;
        new_entry->next = entry->next;
        new_entry->start_time = end_time;
        new_entry->end_time = entry->end_time;
        new_entry->params = entry->params;
        entry->next = new_entry;
        entry->end_time = time_stamp;
        if (t->tail == entry) t->tail = new_entry;
      }
      // If segments aren't aligned, delete from the beginning of subsequent
      // segments
      if (end_time > entry_end_time) {
        aom_film_grain_table_lookup(t, entry_end_time, end_time, 1, 0);
      }
      return 1;
    }
    prev_entry = entry;
    entry = next;
  }
  return 0;
}

aom_codec_err_t aom_film_grain_table_read(
    aom_film_grain_table_t *t, const char *filename,
    struct aom_internal_error_info *error_info) {
  FILE *file = fopen(filename, "rb");
  if (!file) {
    aom_internal_error(error_info, AOM_CODEC_ERROR, "Unable to open %s",
                       filename);
    return error_info->error_code;
  }
  error_info->error_code = AOM_CODEC_OK;

  // Read in one extra character as there should be white space after
  // the header.
  char magic[9];
  if (!fread(magic, 9, 1, file) || memcmp(magic, kFileMagic, 8)) {
    aom_internal_error(error_info, AOM_CODEC_ERROR,
                       "Unable to read (or invalid) file magic");
    fclose(file);
    return error_info->error_code;
  }

  aom_film_grain_table_entry_t *prev_entry = NULL;
  while (!feof(file)) {
    aom_film_grain_table_entry_t *entry = aom_malloc(sizeof(*entry));
    if (!entry) {
      aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
                         "Unable to allocate grain table entry");
      break;
    }
    memset(entry, 0, sizeof(*entry));
    grain_table_entry_read(file, error_info, entry);
    entry->next = NULL;

    if (prev_entry) prev_entry->next = entry;
    if (!t->head) t->head = entry;
    t->tail = entry;
    prev_entry = entry;

    if (error_info->error_code != AOM_CODEC_OK) break;
  }

  fclose(file);
  return error_info->error_code;
}

aom_codec_err_t aom_film_grain_table_write(
    const aom_film_grain_table_t *t, const char *filename,
    struct aom_internal_error_info *error_info) {
  error_info->error_code = AOM_CODEC_OK;

  FILE *file = fopen(filename, "wb");
  if (!file) {
    aom_internal_error(error_info, AOM_CODEC_ERROR, "Unable to open file %s",
                       filename);
    return error_info->error_code;
  }

  if (!fwrite(kFileMagic, 8, 1, file)) {
    aom_internal_error(error_info, AOM_CODEC_ERROR,
                       "Unable to write file magic");
    fclose(file);
    return error_info->error_code;
  }

  fprintf(file, "\n");
  aom_film_grain_table_entry_t *entry = t->head;
  while (entry) {
    grain_table_entry_write(file, entry);
    entry = entry->next;
  }
  fclose(file);
  return error_info->error_code;
}

void aom_film_grain_table_free(aom_film_grain_table_t *t) {
  aom_film_grain_table_entry_t *entry = t->head;
  while (entry) {
    aom_film_grain_table_entry_t *next = entry->next;
    aom_free(entry);
    entry = next;
  }
  memset(t, 0, sizeof(*t));
}
