/*
 * 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.
 */

#include "./aom_scale_rtcd.h"
#include "aom_scale/aom_scale.h"
#include "aom_mem/aom_mem.h"
/****************************************************************************
*  Imports
****************************************************************************/

/****************************************************************************
 *
 *
 *  INPUTS        : const unsigned char *source : Pointer to source data.
 *                  unsigned int source_width   : Stride of source.
 *                  unsigned char *dest         : Pointer to destination data.
 *                  unsigned int dest_width     : Stride of destination
 *                                                (NOT USED).
 *
 *  OUTPUTS       : None.
 *
 *  RETURNS       : void
 *
 *  FUNCTION      : Copies horizontal line of pixels from source to
 *                  destination scaling up by 4 to 5.
 *
 *  SPECIAL NOTES : None.
 *
 ****************************************************************************/
void aom_horizontal_line_5_4_scale_c(const unsigned char *source,
                                     unsigned int source_width,
                                     unsigned char *dest,
                                     unsigned int dest_width) {
  const unsigned char *const source_end = source + source_width;
  (void)dest_width;

  while (source < source_end) {
    const unsigned int a = source[0];
    const unsigned int b = source[1];
    const unsigned int c = source[2];
    const unsigned int d = source[3];
    const unsigned int e = source[4];

    dest[0] = (unsigned char)a;
    dest[1] = (unsigned char)((b * 192 + c * 64 + 128) >> 8);
    dest[2] = (unsigned char)((c * 128 + d * 128 + 128) >> 8);
    dest[3] = (unsigned char)((d * 64 + e * 192 + 128) >> 8);

    source += 5;
    dest += 4;
  }
}

void aom_vertical_band_5_4_scale_c(unsigned char *source,
                                   unsigned int src_pitch, unsigned char *dest,
                                   unsigned int dest_pitch,
                                   unsigned int dest_width) {
  const unsigned char *const dest_end = dest + dest_width;
  while (dest < dest_end) {
    const unsigned int a = source[0 * src_pitch];
    const unsigned int b = source[1 * src_pitch];
    const unsigned int c = source[2 * src_pitch];
    const unsigned int d = source[3 * src_pitch];
    const unsigned int e = source[4 * src_pitch];

    dest[0 * dest_pitch] = (unsigned char)a;
    dest[1 * dest_pitch] = (unsigned char)((b * 192 + c * 64 + 128) >> 8);
    dest[2 * dest_pitch] = (unsigned char)((c * 128 + d * 128 + 128) >> 8);
    dest[3 * dest_pitch] = (unsigned char)((d * 64 + e * 192 + 128) >> 8);

    ++source;
    ++dest;
  }
}

/*7***************************************************************************
 *
 *  ROUTINE       : aom_horizontal_line_3_5_scale_c
 *
 *  INPUTS        : const unsigned char *source : Pointer to source data.
 *                  unsigned int source_width   : Stride of source.
 *                  unsigned char *dest         : Pointer to destination data.
 *                  unsigned int dest_width     : Stride of destination
 *                                                (NOT USED).
 *
 *  OUTPUTS       : None.
 *
 *  RETURNS       : void
 *
 *  FUNCTION      : Copies horizontal line of pixels from source to
 *                  destination scaling up by 3 to 5.
 *
 *  SPECIAL NOTES : None.
 *
 *
 ****************************************************************************/
void aom_horizontal_line_5_3_scale_c(const unsigned char *source,
                                     unsigned int source_width,
                                     unsigned char *dest,
                                     unsigned int dest_width) {
  const unsigned char *const source_end = source + source_width;
  (void)dest_width;
  while (source < source_end) {
    const unsigned int a = source[0];
    const unsigned int b = source[1];
    const unsigned int c = source[2];
    const unsigned int d = source[3];
    const unsigned int e = source[4];

    dest[0] = (unsigned char)a;
    dest[1] = (unsigned char)((b * 85 + c * 171 + 128) >> 8);
    dest[2] = (unsigned char)((d * 171 + e * 85 + 128) >> 8);

    source += 5;
    dest += 3;
  }
}

void aom_vertical_band_5_3_scale_c(unsigned char *source,
                                   unsigned int src_pitch, unsigned char *dest,
                                   unsigned int dest_pitch,
                                   unsigned int dest_width) {
  const unsigned char *const dest_end = dest + dest_width;
  while (dest < dest_end) {
    const unsigned int a = source[0 * src_pitch];
    const unsigned int b = source[1 * src_pitch];
    const unsigned int c = source[2 * src_pitch];
    const unsigned int d = source[3 * src_pitch];
    const unsigned int e = source[4 * src_pitch];

    dest[0 * dest_pitch] = (unsigned char)a;
    dest[1 * dest_pitch] = (unsigned char)((b * 85 + c * 171 + 128) >> 8);
    dest[2 * dest_pitch] = (unsigned char)((d * 171 + e * 85 + 128) >> 8);

    ++source;
    ++dest;
  }
}

/****************************************************************************
 *
 *  ROUTINE       : aom_horizontal_line_1_2_scale_c
 *
 *  INPUTS        : const unsigned char *source : Pointer to source data.
 *                  unsigned int source_width   : Stride of source.
 *                  unsigned char *dest         : Pointer to destination data.
 *                  unsigned int dest_width     : Stride of destination
 *                                                (NOT USED).
 *
 *  OUTPUTS       : None.
 *
 *  RETURNS       : void
 *
 *  FUNCTION      : Copies horizontal line of pixels from source to
 *                  destination scaling up by 1 to 2.
 *
 *  SPECIAL NOTES : None.
 *
 ****************************************************************************/
void aom_horizontal_line_2_1_scale_c(const unsigned char *source,
                                     unsigned int source_width,
                                     unsigned char *dest,
                                     unsigned int dest_width) {
  const unsigned char *const source_end = source + source_width;
  (void)dest_width;
  while (source < source_end) {
    dest[0] = source[0];
    source += 2;
    ++dest;
  }
}

void aom_vertical_band_2_1_scale_c(unsigned char *source,
                                   unsigned int src_pitch, unsigned char *dest,
                                   unsigned int dest_pitch,
                                   unsigned int dest_width) {
  (void)dest_pitch;
  (void)src_pitch;
  memcpy(dest, source, dest_width);
}

void aom_vertical_band_2_1_scale_i_c(unsigned char *source,
                                     unsigned int src_pitch,
                                     unsigned char *dest,
                                     unsigned int dest_pitch,
                                     unsigned int dest_width) {
  const unsigned char *const dest_end = dest + dest_width;
  (void)dest_pitch;
  while (dest < dest_end) {
    const unsigned int a = source[-src_pitch] * 3;
    const unsigned int b = source[0] * 10;
    const unsigned int c = source[src_pitch] * 3;
    dest[0] = (unsigned char)((8 + a + b + c) >> 4);
    ++source;
    ++dest;
  }
}
