/*
 * Copyright (c) 2017, 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.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "./obudec.h"

#include "aom_ports/mem_ops.h"
#include "av1/common/common.h"
#include "av1/decoder/obu.h"

#define OBU_BUFFER_SIZE (500 * 1024)

#define OBU_HEADER_SIZE 1
#define OBU_EXTENSION_SIZE 1
#define OBU_MAX_LENGTH_FIELD_SIZE 8
#define OBU_DETECTION_SIZE \
  (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 3 * OBU_MAX_LENGTH_FIELD_SIZE)

// Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
// Stores raw bytes in 'value_buffer', length of the number in 'value_length',
// and decoded value in 'value'.
static int obudec_read_leb128(FILE *f, uint8_t *value_buffer,
                              uint64_t *value_length, uint64_t *value) {
  if (!f || !value_buffer || !value_length || !value) return -1;
  for (int len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
    const size_t num_read = fread(&value_buffer[len], 1, 1, f);
    if (num_read == 0 && feof(f)) {
      *value_length = 0;
      return 0;
    }
    if (num_read != 1) {
      // Ran out of data before completing read of value.
      return -1;
    }
    if ((value_buffer[len] >> 7) == 0) {
      *value_length = (size_t)(len + 1);
      break;
    }
  }

  return aom_uleb_decode(value_buffer, OBU_MAX_LENGTH_FIELD_SIZE, value, NULL);
}

// Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
// enough to store an OBU header with extension (2 bytes). Raw OBU data is
// written to 'obu_data', parsed OBU header values are written to 'obu_header',
// and total bytes read from file are written to 'bytes_read'. Returns 0 for
// success, and non-zero on failure. When end of file is reached, the return
// value is 0 and the 'bytes_read' value is set to 0.
static int obudec_read_obu_header(FILE *f, size_t buffer_capacity,
                                  int is_annexb, uint8_t *obu_data,
                                  ObuHeader *obu_header, uint64_t *bytes_read) {
  if (!f || buffer_capacity < (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE) ||
      !obu_data || !obu_header || !bytes_read) {
    return -1;
  }
  *bytes_read = fread(obu_data, 1, 1, f);

  if (feof(f) && *bytes_read == 0) {
    return 0;
  } else if (*bytes_read != 1) {
    fprintf(stderr, "obudec: Failure reading OBU header.\n");
    return -1;
  }

  const int has_extension = (obu_data[0] >> 2) & 0x1;
  if (has_extension) {
    if (fread(&obu_data[1], 1, 1, f) != 1) {
      fprintf(stderr, "obudec: Failure reading OBU extension.");
      return -1;
    }
    ++*bytes_read;
  }

  size_t obu_bytes_parsed = 0;
  const aom_codec_err_t parse_result = aom_read_obu_header(
      obu_data, *bytes_read, &obu_bytes_parsed, obu_header, is_annexb);
  if (parse_result != AOM_CODEC_OK || *bytes_read != obu_bytes_parsed) {
    fprintf(stderr, "obudec: Error parsing OBU header.\n");
    return -1;
  }

  return 0;
}

// Reads OBU payload from 'f' and returns 0 for success when all payload bytes
// are read from the file. Payload data is written to 'obu_data', and actual
// bytes read written to 'bytes_read'.
static int obudec_read_obu_payload(FILE *f, uint64_t payload_length,
                                   uint8_t *obu_data, uint64_t *bytes_read) {
  if (!f || payload_length == 0 || !obu_data || !bytes_read) return -1;

  if (fread(obu_data, 1, (size_t)payload_length, f) != payload_length) {
    fprintf(stderr, "obudec: Failure reading OBU payload.\n");
    return -1;
  }

  *bytes_read += payload_length;
  return 0;
}

static int obudec_read_obu_header_and_size(FILE *f, size_t buffer_capacity,
                                           int is_annexb, uint8_t *buffer,
                                           uint64_t *bytes_read,
                                           uint64_t *payload_length,
                                           ObuHeader *obu_header) {
  const size_t kMinimumBufferSize =
      (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + OBU_MAX_LENGTH_FIELD_SIZE);
  if (!f || !buffer || !bytes_read || !payload_length || !obu_header ||
      buffer_capacity < kMinimumBufferSize) {
    return -1;
  }

  uint64_t leb128_length = 0;
  uint64_t obu_size = 0;
  uint64_t header_size = 0;
  if (is_annexb) {
    if (obudec_read_leb128(f, &buffer[0], &leb128_length, &obu_size) != 0) {
      fprintf(stderr, "obudec: Failure reading OBU size length.\n");
      return -1;
    } else if (leb128_length == 0) {
      *payload_length = 0;
      return 0;
    }
  }

  if (obudec_read_obu_header(f, buffer_capacity, is_annexb,
                             buffer + leb128_length, obu_header,
                             &header_size) != 0) {
    return -1;
  } else if (header_size == 0) {
    *payload_length = 0;
    return 0;
  }

  if (is_annexb) {
    if (obu_size < header_size) {
      fprintf(stderr, "obudec: OBU size is too small.\n");
      return -1;
    }
    *payload_length = obu_size - header_size;
  } else {
    if (obudec_read_leb128(f, &buffer[header_size], &leb128_length,
                           payload_length) != 0) {
      fprintf(stderr, "obudec: Failure reading OBU payload length.\n");
      return -1;
    }
  }

  *bytes_read = leb128_length + header_size;
  return 0;
}

static int obudec_read_one_obu(FILE *f, uint8_t **obu_buffer,
                               size_t obu_bytes_buffered,
                               size_t *obu_buffer_capacity,
                               uint64_t *obu_length, ObuHeader *obu_header,
                               int is_annexb) {
  uint64_t available_buffer_capacity =
      *obu_buffer_capacity - obu_bytes_buffered;

  if (!(*obu_buffer)) return -1;

  uint64_t obu_payload_length = 0;
  uint64_t bytes_read = 0;
  const int status = obudec_read_obu_header_and_size(
      f, available_buffer_capacity, is_annexb, *obu_buffer + obu_bytes_buffered,
      &bytes_read, &obu_payload_length, obu_header);
  if (status < 0) return status;

  if (obu_payload_length > UINT64_MAX - bytes_read) return -1;

  if (obu_payload_length > 256 * 1024 * 1024) {
    warn("obudec: Read invalid OBU size (%u)\n",
         (unsigned int)obu_payload_length);
    *obu_length = bytes_read + obu_payload_length;
    return -1;
  }

  if (bytes_read + obu_payload_length > available_buffer_capacity) {
    uint64_t new_capacity =
        obu_bytes_buffered + bytes_read + 2 * obu_payload_length;
    uint8_t *new_buffer = (uint8_t *)realloc(*obu_buffer, new_capacity);

    if (new_buffer) {
      *obu_buffer = new_buffer;
      *obu_buffer_capacity = new_capacity;
    } else {
      warn("obudec: Failed to allocate compressed data buffer\n");
      *obu_length = bytes_read + obu_payload_length;
      return -1;
    }
  }

  if (obu_payload_length > 0 &&
      obudec_read_obu_payload(f, obu_payload_length,
                              *obu_buffer + obu_bytes_buffered + bytes_read,
                              &bytes_read) != 0) {
    return -1;
  }

  *obu_length = bytes_read;
  return 0;
}

int file_is_obu(struct ObuDecInputContext *obu_ctx) {
  if (!obu_ctx || !obu_ctx->avx_ctx) return 0;

  struct AvxInputContext *avx_ctx = obu_ctx->avx_ctx;
  uint8_t detect_buf[OBU_DETECTION_SIZE] = { 0 };
  const int is_annexb = obu_ctx->is_annexb;
  FILE *f = avx_ctx->file;
  uint64_t bytes_read = 0;
  uint64_t payload_length = 0;
  ObuHeader obu_header;
  memset(&obu_header, 0, sizeof(obu_header));
  uint64_t length_of_unit_size = 0;
  uint64_t unit_size;
  uint64_t annexb_header_length = 0;

  if (is_annexb) {
    // read the size of first temporal unit
    if (obudec_read_leb128(f, &detect_buf[0], &length_of_unit_size,
                           &unit_size) != 0) {
      fprintf(stderr, "obudec: Failure reading temporal unit header\n");
      return 0;
    }

    // read the size of first frame unit
    if (obudec_read_leb128(f, &detect_buf[length_of_unit_size],
                           &annexb_header_length, &unit_size) != 0) {
      fprintf(stderr, "obudec: Failure reading frame unit header\n");
      return 0;
    }
    annexb_header_length += length_of_unit_size;
  }

  if (obudec_read_obu_header_and_size(
          f, OBU_DETECTION_SIZE - annexb_header_length, is_annexb,
          &detect_buf[annexb_header_length], &bytes_read, &payload_length,
          &obu_header) != 0) {
    fprintf(stderr, "obudec: Failure reading first OBU.\n");
    rewind(f);
    return 0;
  }

  if (obu_header.type != OBU_TEMPORAL_DELIMITER &&
      obu_header.type != OBU_SEQUENCE_HEADER) {
    return 0;
  }

  if (obu_header.has_length_field) {
    if (obu_header.type == OBU_TEMPORAL_DELIMITER && payload_length != 0) {
      fprintf(
          stderr,
          "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
      rewind(f);
      return 0;
    }
  } else if (!is_annexb) {
    fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
    rewind(f);
    return 0;
  }

  // Appears that input is valid Section 5 AV1 stream.
  obu_ctx->buffer = (uint8_t *)calloc(OBU_BUFFER_SIZE, 1);
  if (!obu_ctx->buffer) {
    fprintf(stderr, "Out of memory.\n");
    rewind(f);
    return 0;
  }
  obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;

  if (is_annexb) {
    bytes_read += annexb_header_length;
  }
  memcpy(obu_ctx->buffer, &detect_buf[0], (size_t)bytes_read);
  obu_ctx->bytes_buffered = (size_t)bytes_read;
  // If the first OBU is a SEQUENCE_HEADER, then it will have a payload.
  // We need to read this in so that our buffer only contains complete OBUs.
  if (payload_length > 0) {
    if (payload_length > (obu_ctx->buffer_capacity - bytes_read)) {
      fprintf(stderr, "obudec: First OBU's payload is too large\n");
      rewind(f);
      return 0;
    }

    uint64_t payload_bytes = 0;
    const int status = obudec_read_obu_payload(
        f, payload_length, &obu_ctx->buffer[bytes_read], &payload_bytes);
    if (status < 0) {
      rewind(f);
      return 0;
    }
    obu_ctx->bytes_buffered += payload_bytes;
  }
  return 1;
}

int obudec_read_temporal_unit(struct ObuDecInputContext *obu_ctx,
                              uint8_t **buffer, size_t *bytes_read,
                              size_t *buffer_size) {
  FILE *f = obu_ctx->avx_ctx->file;
  if (!f) return -1;

  *buffer_size = 0;
  *bytes_read = 0;

  if (feof(f)) {
    return 1;
  }

  uint64_t tu_size;
  uint64_t obu_size = 0;
  uint64_t length_of_temporal_unit_size = 0;
  uint8_t tuheader[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };

  if (obu_ctx->is_annexb) {
    uint64_t size = 0;

    if (obu_ctx->bytes_buffered == 0) {
      if (obudec_read_leb128(f, &tuheader[0], &length_of_temporal_unit_size,
                             &size) != 0) {
        fprintf(stderr, "obudec: Failure reading temporal unit header\n");
        return -1;
      }
      if (size == 0 && feof(f)) {
        return 1;
      }
    } else {
      // temporal unit size was already stored in buffer
      size_t bytes_consumed = 0;
      if (aom_uleb_decode(obu_ctx->buffer, obu_ctx->bytes_buffered, &size,
                          &bytes_consumed) != 0) {
        fprintf(stderr, "obudec: Failure reading temporal unit header\n");
        return -1;
      }
      length_of_temporal_unit_size += bytes_consumed;
    }

    size += length_of_temporal_unit_size;
    tu_size = size;
  } else {
    while (1) {
      ObuHeader obu_header;
      memset(&obu_header, 0, sizeof(obu_header));

      if (obudec_read_one_obu(f, &obu_ctx->buffer, obu_ctx->bytes_buffered,
                              &obu_ctx->buffer_capacity, &obu_size, &obu_header,
                              0) != 0) {
        fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
        return -1;
      }

      if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0 ||
          (obu_header.has_extension &&
           obu_header.enhancement_layer_id > obu_ctx->last_layer_id)) {
        tu_size = obu_ctx->bytes_buffered;
        break;
      } else {
        obu_ctx->bytes_buffered += (size_t)obu_size;
      }
    }
  }

#if defined AOM_MAX_ALLOCABLE_MEMORY
  if (tu_size > AOM_MAX_ALLOCABLE_MEMORY) {
    fprintf(stderr, "obudec: Temporal Unit size exceeds max alloc size.\n");
    return -1;
  }
#endif
  uint8_t *new_buffer = (uint8_t *)realloc(*buffer, (size_t)tu_size);
  if (!new_buffer) {
    free(*buffer);
    fprintf(stderr, "obudec: Out of memory.\n");
    return -1;
  }
  *buffer = new_buffer;
  *bytes_read = (size_t)tu_size;
  *buffer_size = (size_t)tu_size;

  if (!obu_ctx->is_annexb) {
    memcpy(*buffer, obu_ctx->buffer, (size_t)tu_size);

    // At this point, (obu_ctx->buffer + obu_ctx->bytes_buffered + obu_size)
    // points to the end of the buffer.
    memmove(obu_ctx->buffer, obu_ctx->buffer + obu_ctx->bytes_buffered,
            (size_t)obu_size);
    obu_ctx->bytes_buffered = (size_t)obu_size;
  } else {
    if (!feof(f)) {
      size_t data_size;
      size_t offset;
      if (!obu_ctx->bytes_buffered) {
        data_size = (uint32_t)(tu_size - length_of_temporal_unit_size);
        memcpy(*buffer, &tuheader[0], length_of_temporal_unit_size);
        offset = length_of_temporal_unit_size;
      } else {
        memcpy(*buffer, obu_ctx->buffer, obu_ctx->bytes_buffered);
        offset = obu_ctx->bytes_buffered;
        data_size = tu_size - obu_ctx->bytes_buffered;
        obu_ctx->bytes_buffered = 0;
      }

      if (fread(new_buffer + offset, 1, data_size, f) != data_size) {
        fprintf(stderr, "obudec: Failed to read full temporal unit\n");
        return -1;
      }
    }
  }
  return 0;
}

void obudec_free(struct ObuDecInputContext *obu_ctx) { free(obu_ctx->buffer); }
