/*
 * 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;
      }
    }

    fscanf(file, "\n\tcY");
    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;
      }
    }
    fscanf(file, "\n\tcCb");
    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;
      }
    }
    fscanf(file, "\n\tcCr");
    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;
      }
    }
    fscanf(file, "\n");
  }
}

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");
  }
}

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));
    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 = 0;
  int16_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));
        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 beggining 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 = 0;
  while (!feof(file)) {
    aom_film_grain_table_entry_t *entry = aom_malloc(sizeof(*entry));
    memset(entry, 0, sizeof(*entry));
    grain_table_entry_read(file, error_info, entry);
    entry->next = 0;

    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));
}
