<commit_before>/*****************************************************************************
 * This file is part of Kvazaar HEVC encoder.
 *
 * Copyright (C) 2013-2014 Tampere University of Technology and others (see
 * COPYING file).
 *
 * Kvazaar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * Kvazaar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Kvazaar.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************/

/*
 * \file
 */

#include "inter.h"

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

#include "config.h"
#include "filter.h"

/**
 * \brief Set block info to the CU structure
 * \param pic picture to use
 * \param x_cu x CU position (smallest CU)
 * \param y_cu y CU position (smallest CU)
 * \param depth current CU depth
 * \param cur_cu CU to take the settings from
 * \returns Void
*/
void inter_set_block(videoframe* frame, uint32_t x_cu, uint32_t y_cu, uint8_t depth, cu_info* cur_cu)
{
  uint32_t x, y;
  // Width in smallest CU
  int block_scu_width = (LCU_WIDTH>>depth)/(LCU_WIDTH>>MAX_DEPTH);
  int tr_depth = (depth == 0 ? 1 : depth);
  // Loop through all the block in the area of cur_cu
  for (y = y_cu; y < y_cu + block_scu_width; y++) {
    for (x = x_cu; x < x_cu + block_scu_width; x++) {
      cu_info * const cu = videoframe_get_cu(frame, x, y);
      // Set all SCU's to this blocks values at the bottom most depth.
      cu->depth = depth;
      cu->type  = CU_INTER;
      cu->part_size = SIZE_2Nx2N;
      cu->inter.mode   = cur_cu->inter.mode;
      cu->inter.mv[0]  = cur_cu->inter.mv[0];
      cu->inter.mv[1]  = cur_cu->inter.mv[1];
      cu->inter.mv_dir = cur_cu->inter.mv_dir;
      cu->inter.mv_ref = cur_cu->inter.mv_ref;
      cu->tr_depth = tr_depth;
    }
  }
}

void extend_borders(int xpos, int ypos, int mv_x, int mv_y, int off_x, int off_y, pixel *ref, int ref_width, int ref_height,
    int filterSize, int width, int height, int16_t *dst) {

  int16_t mv[2] = {mv_x, mv_y};
  int halfFilterSize = filterSize>>1;

  int dst_y; int y; int dst_x; int x; int coord_x; int coord_y;
  int8_t overflow_neg_y_temp,overflow_pos_y_temp,overflow_neg_x_temp,overflow_pos_x_temp;

  for (dst_y = 0, y = ypos - halfFilterSize; y < ((ypos + height)) + halfFilterSize; dst_y++, y++) {

    // calculate y-pixel offset
    coord_y = y + off_y + mv[1];

    // On y-overflow set coord_y accordingly
    overflow_neg_y_temp = (coord_y < 0) ? 1 : 0;
    overflow_pos_y_temp = (coord_y >= ref_height) ? 1 : 0;
    if (overflow_neg_y_temp)      coord_y = 0;
    else if (overflow_pos_y_temp) coord_y = (ref_height) - 1;
    coord_y *= ref_width;

    for (dst_x = 0, x = (xpos) - halfFilterSize; x < ((xpos + width)) + halfFilterSize; dst_x++, x++) {
      coord_x = x + off_x + mv[0];

      // On x-overflow set coord_x accordingly
      overflow_neg_x_temp = (coord_x < 0) ? 1 : 0;
      overflow_pos_x_temp = (coord_x >= ref_width) ? 1 : 0;
      if (overflow_neg_x_temp)      coord_x = 0;
      else if (overflow_pos_x_temp) coord_x = ref_width - 1;

      // Store source block data (with extended borders)
      dst[dst_y*(width+filterSize) + dst_x] = ref[coord_y + coord_x];
    }
  }
}

/**
 * \brief Reconstruct inter block
 * \param ref picture to copy the data from
 * \param xpos block x position
 * \param ypos block y position
 * \param width block width
 * \param mv[2] motion vector
 * \param lcu destination lcu
 * \returns Void
*/
void inter_recon_lcu(const encoder_state * const encoder_state, const image * const ref, int32_t xpos, int32_t ypos,int32_t width, const int16_t mv_param[2], lcu_t *lcu)
{
  int x,y,coord_x,coord_y;
  int16_t mv[2] = { mv_param[0], mv_param[1] };

  int32_t dst_width_c = LCU_WIDTH>>1; //!< Destination picture width in chroma pixels
  int32_t ref_width_c = ref->width>>1; //!< Reference picture width in chroma pixels

  // negative overflow flag
  int8_t overflow_neg_x = (encoder_state->tile->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) < 0)?1:0;
  int8_t overflow_neg_y = (encoder_state->tile->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) < 0)?1:0;

  // positive overflow flag
  int8_t overflow_pos_x = (encoder_state->tile->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) + width > ref->width )?1:0;
  int8_t overflow_pos_y = (encoder_state->tile->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) + width > ref->height)?1:0;

  // Chroma half-pel
  #define HALFPEL_CHROMA_WIDTH ((LCU_WIDTH>>1) + 8)
  int8_t chroma_halfpel = ((mv[0]>>2)&1) || ((mv[1]>>2)&1); //!< (luma integer mv) lsb is set -> chroma is half-pel
  int16_t halfpel_src_u[HALFPEL_CHROMA_WIDTH * HALFPEL_CHROMA_WIDTH]; //!< U source block for interpolation
  int16_t halfpel_src_v[HALFPEL_CHROMA_WIDTH * HALFPEL_CHROMA_WIDTH]; //!< V source block for interpolation
  int16_t *halfpel_src_off_u = &halfpel_src_u[HALFPEL_CHROMA_WIDTH*4 + 4]; //!< halfpel_src_u with offset (4,4)
  int16_t *halfpel_src_off_v = &halfpel_src_v[HALFPEL_CHROMA_WIDTH*4 + 4]; //!< halfpel_src_v with offset (4,4)
  int16_t halfpel_u[LCU_WIDTH * LCU_WIDTH]; //!< interpolated 2W x 2H block (u)
  int16_t halfpel_v[LCU_WIDTH * LCU_WIDTH]; //!< interpolated 2W x 2H block (v)

  // Luma quarter-pel
    int8_t fractional_mv = (mv[0]&1) || (mv[1]&1) || (mv[0]&2) || (mv[1]&2); // either of 2 lowest bits of mv set -> mv is fractional

    if(fractional_mv) {
      int y_off_x = (mv[0]&3);
      int y_off_y = (mv[1]&3);

      int c_off_x = (mv[0]&7);
      int c_off_y = (mv[1]&7);

      int y,x;

      #define FILTER_SIZE_Y 8 //Luma filter size
      #define FILTER_SIZE_C 4 //Chroma filter size

      // Fractional luma 1/4-pel
      int16_t qpel_src_y[(LCU_WIDTH+FILTER_SIZE_Y) * (LCU_WIDTH+FILTER_SIZE_Y)];
      int16_t* qpel_src_off_y = &qpel_src_y[(width+FILTER_SIZE_Y)*(FILTER_SIZE_Y>>1)+(FILTER_SIZE_Y>>1)];
      int16_t qpel_dst_y[LCU_WIDTH*LCU_WIDTH*16];

      // Fractional chroma 1/8-pel
      int width_c = width>>1;
      int16_t octpel_src_u[((LCU_WIDTH>>1)+FILTER_SIZE_C) * ((LCU_WIDTH>>1)+FILTER_SIZE_C)];
      int16_t* octpel_src_off_u = &octpel_src_u[(width_c+FILTER_SIZE_C)*(FILTER_SIZE_C>>1)+(FILTER_SIZE_C>>1)];
      int16_t octpel_dst_u[(LCU_WIDTH>>1)*(LCU_WIDTH>>1)*64];

      int16_t octpel_src_v[((LCU_WIDTH>>1)+FILTER_SIZE_C) * ((LCU_WIDTH>>1)+FILTER_SIZE_C)];
      int16_t* octpel_src_off_v = &octpel_src_v[(width_c+FILTER_SIZE_C)*(FILTER_SIZE_C>>1)+(FILTER_SIZE_C>>1)];
      int16_t octpel_dst_v[(LCU_WIDTH>>1)*(LCU_WIDTH>>1)*64];

      // Fractional luma
      extend_borders(xpos, ypos, mv[0]>>2, mv[1]>>2, encoder_state->tile->lcu_offset_x * LCU_WIDTH, encoder_state->tile->lcu_offset_y * LCU_WIDTH,
          ref->y, ref->width, ref->height, FILTER_SIZE_Y, width, width, qpel_src_y);

      filter_inter_quarterpel_luma(encoder_state->encoder_control, qpel_src_off_y, width+FILTER_SIZE_Y, width,
                                   width, qpel_dst_y, width*4, y_off_x, y_off_y);

      //Fractional chroma U
      extend_borders(xpos>>1, ypos>>1, (mv[0]>>2)>>1, (mv[1]>>2)>>1, encoder_state->tile->lcu_offset_x * (LCU_WIDTH>>1), encoder_state->tile->lcu_offset_y * (LCU_WIDTH>>1),
          ref->u, ref->width>>1, ref->height>>1, FILTER_SIZE_C, width_c, width_c, octpel_src_u);

      filter_inter_octpel_chroma(encoder_state->encoder_control, octpel_src_off_u, width_c+FILTER_SIZE_C, width_c,
                                 width_c, octpel_dst_u, width_c*8, c_off_x, c_off_y);

      //Fractional chroma V
      extend_borders(xpos>>1, ypos>>1, (mv[0]>>2)>>1, (mv[1]>>2)>>1, encoder_state->tile->lcu_offset_x * (LCU_WIDTH>>1), encoder_state->tile->lcu_offset_y * (LCU_WIDTH>>1),
          ref->v, ref->width>>1, ref->height>>1, FILTER_SIZE_C, width_c, width_c, octpel_src_v);

      filter_inter_octpel_chroma(encoder_state->encoder_control, octpel_src_off_v, width_c+FILTER_SIZE_C, width_c,
                   width_c, octpel_dst_v, width_c*8, c_off_x, c_off_y);

      //Luma
      for(y = 0; y < width; ++y) {
        int y_in_lcu = ((y+ypos) & ((LCU_WIDTH)-1));
        int qpel_y = y*4+y_off_y;
        for(x = 0; x < width; ++x) {
          int x_in_lcu = ((x+xpos) & ((LCU_WIDTH)-1));
          int qpel_x = x*4+y_off_x;
          lcu->rec.y[y_in_lcu * LCU_WIDTH + x_in_lcu] = (pixel)qpel_dst_y[qpel_y*(width*4)+qpel_x];
        }
      }
      //Chroma
      for(y = 0; y < width_c; ++y) {
        int y_in_lcu = ((y+(ypos>>1)) & ((LCU_WIDTH>>1)-1));<commit_msg>Clarified comments a bit<commit_after>/*****************************************************************************
 * This file is part of Kvazaar HEVC encoder.
 *
 * Copyright (C) 2013-2014 Tampere University of Technology and others (see
 * COPYING file).
 *
 * Kvazaar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * Kvazaar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Kvazaar.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************/

/*
 * \file
 */

#include "inter.h"

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

#include "config.h"
#include "filter.h"

/**
 * \brief Set block info to the CU structure
 * \param pic picture to use
 * \param x_cu x CU position (smallest CU)
 * \param y_cu y CU position (smallest CU)
 * \param depth current CU depth
 * \param cur_cu CU to take the settings from
 * \returns Void
*/
void inter_set_block(videoframe* frame, uint32_t x_cu, uint32_t y_cu, uint8_t depth, cu_info* cur_cu)
{
  uint32_t x, y;
  // Width in smallest CU
  int block_scu_width = (LCU_WIDTH>>depth)/(LCU_WIDTH>>MAX_DEPTH);
  int tr_depth = (depth == 0 ? 1 : depth);
  // Loop through all the block in the area of cur_cu
  for (y = y_cu; y < y_cu + block_scu_width; y++) {
    for (x = x_cu; x < x_cu + block_scu_width; x++) {
      cu_info * const cu = videoframe_get_cu(frame, x, y);
      // Set all SCU's to this blocks values at the bottom most depth.
      cu->depth = depth;
      cu->type  = CU_INTER;
      cu->part_size = SIZE_2Nx2N;
      cu->inter.mode   = cur_cu->inter.mode;
      cu->inter.mv[0]  = cur_cu->inter.mv[0];
      cu->inter.mv[1]  = cur_cu->inter.mv[1];
      cu->inter.mv_dir = cur_cu->inter.mv_dir;
      cu->inter.mv_ref = cur_cu->inter.mv_ref;
      cu->tr_depth = tr_depth;
    }
  }
}

void extend_borders(int xpos, int ypos, int mv_x, int mv_y, int off_x, int off_y, pixel *ref, int ref_width, int ref_height,
    int filterSize, int width, int height, int16_t *dst) {

  int16_t mv[2] = {mv_x, mv_y};
  int halfFilterSize = filterSize>>1;

  int dst_y; int y; int dst_x; int x; int coord_x; int coord_y;
  int8_t overflow_neg_y_temp,overflow_pos_y_temp,overflow_neg_x_temp,overflow_pos_x_temp;

  for (dst_y = 0, y = ypos - halfFilterSize; y < ((ypos + height)) + halfFilterSize; dst_y++, y++) {

    // calculate y-pixel offset
    coord_y = y + off_y + mv[1];

    // On y-overflow set coord_y accordingly
    overflow_neg_y_temp = (coord_y < 0) ? 1 : 0;
    overflow_pos_y_temp = (coord_y >= ref_height) ? 1 : 0;
    if (overflow_neg_y_temp)      coord_y = 0;
    else if (overflow_pos_y_temp) coord_y = (ref_height) - 1;
    coord_y *= ref_width;

    for (dst_x = 0, x = (xpos) - halfFilterSize; x < ((xpos + width)) + halfFilterSize; dst_x++, x++) {
      coord_x = x + off_x + mv[0];

      // On x-overflow set coord_x accordingly
      overflow_neg_x_temp = (coord_x < 0) ? 1 : 0;
      overflow_pos_x_temp = (coord_x >= ref_width) ? 1 : 0;
      if (overflow_neg_x_temp)      coord_x = 0;
      else if (overflow_pos_x_temp) coord_x = ref_width - 1;

      // Store source block data (with extended borders)
      dst[dst_y*(width+filterSize) + dst_x] = ref[coord_y + coord_x];
    }
  }
}

/**
 * \brief Reconstruct inter block
 * \param ref picture to copy the data from
 * \param xpos block x position
 * \param ypos block y position
 * \param width block width
 * \param mv[2] motion vector
 * \param lcu destination lcu
 * \returns Void
*/
void inter_recon_lcu(const encoder_state * const encoder_state, const image * const ref, int32_t xpos, int32_t ypos,int32_t width, const int16_t mv_param[2], lcu_t *lcu)
{
  int x,y,coord_x,coord_y;
  int16_t mv[2] = { mv_param[0], mv_param[1] };

  int32_t dst_width_c = LCU_WIDTH>>1; //!< Destination picture width in chroma pixels
  int32_t ref_width_c = ref->width>>1; //!< Reference picture width in chroma pixels

  // negative overflow flag
  int8_t overflow_neg_x = (encoder_state->tile->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) < 0)?1:0;
  int8_t overflow_neg_y = (encoder_state->tile->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) < 0)?1:0;

  // positive overflow flag
  int8_t overflow_pos_x = (encoder_state->tile->lcu_offset_x * LCU_WIDTH + xpos + (mv[0]>>2) + width > ref->width )?1:0;
  int8_t overflow_pos_y = (encoder_state->tile->lcu_offset_y * LCU_WIDTH + ypos + (mv[1]>>2) + width > ref->height)?1:0;

  // Chroma half-pel
  #define HALFPEL_CHROMA_WIDTH ((LCU_WIDTH>>1) + 8)
  int8_t chroma_halfpel = ((mv[0]>>2)&1) || ((mv[1]>>2)&1); //!< (luma integer mv) lsb is set -> chroma is half-pel
  int16_t halfpel_src_u[HALFPEL_CHROMA_WIDTH * HALFPEL_CHROMA_WIDTH]; //!< U source block for interpolation
  int16_t halfpel_src_v[HALFPEL_CHROMA_WIDTH * HALFPEL_CHROMA_WIDTH]; //!< V source block for interpolation
  int16_t *halfpel_src_off_u = &halfpel_src_u[HALFPEL_CHROMA_WIDTH*4 + 4]; //!< halfpel_src_u with offset (4,4)
  int16_t *halfpel_src_off_v = &halfpel_src_v[HALFPEL_CHROMA_WIDTH*4 + 4]; //!< halfpel_src_v with offset (4,4)
  int16_t halfpel_u[LCU_WIDTH * LCU_WIDTH]; //!< interpolated 2W x 2H block (u)
  int16_t halfpel_v[LCU_WIDTH * LCU_WIDTH]; //!< interpolated 2W x 2H block (v)

  // Luma quarter-pel
    int8_t fractional_mv = (mv[0]&1) || (mv[1]&1) || (mv[0]&2) || (mv[1]&2); // either of 2 lowest bits of mv set -> mv is fractional

    if(fractional_mv) {
      int y_off_x = (mv[0]&3);
      int y_off_y = (mv[1]&3);

      int c_off_x = (mv[0]&7);
      int c_off_y = (mv[1]&7);

      int y,x;

      #define FILTER_SIZE_Y 8 //Luma filter size
      #define FILTER_SIZE_C 4 //Chroma filter size

      // Fractional luma 1/4-pel
      int16_t qpel_src_y[(LCU_WIDTH+FILTER_SIZE_Y) * (LCU_WIDTH+FILTER_SIZE_Y)];
      int16_t* qpel_src_off_y = &qpel_src_y[(width+FILTER_SIZE_Y)*(FILTER_SIZE_Y>>1)+(FILTER_SIZE_Y>>1)];
      int16_t qpel_dst_y[LCU_WIDTH*LCU_WIDTH*16];

      // Fractional chroma 1/8-pel
      int width_c = width>>1;
      int16_t octpel_src_u[((LCU_WIDTH>>1)+FILTER_SIZE_C) * ((LCU_WIDTH>>1)+FILTER_SIZE_C)];
      int16_t* octpel_src_off_u = &octpel_src_u[(width_c+FILTER_SIZE_C)*(FILTER_SIZE_C>>1)+(FILTER_SIZE_C>>1)];
      int16_t octpel_dst_u[(LCU_WIDTH>>1)*(LCU_WIDTH>>1)*64];

      int16_t octpel_src_v[((LCU_WIDTH>>1)+FILTER_SIZE_C) * ((LCU_WIDTH>>1)+FILTER_SIZE_C)];
      int16_t* octpel_src_off_v = &octpel_src_v[(width_c+FILTER_SIZE_C)*(FILTER_SIZE_C>>1)+(FILTER_SIZE_C>>1)];
      int16_t octpel_dst_v[(LCU_WIDTH>>1)*(LCU_WIDTH>>1)*64];

      // Fractional luma
      extend_borders(xpos, ypos, mv[0]>>2, mv[1]>>2, encoder_state->tile->lcu_offset_x * LCU_WIDTH, encoder_state->tile->lcu_offset_y * LCU_WIDTH,
          ref->y, ref->width, ref->height, FILTER_SIZE_Y, width, width, qpel_src_y);

      filter_inter_quarterpel_luma(encoder_state->encoder_control, qpel_src_off_y, width+FILTER_SIZE_Y, width,
                                   width, qpel_dst_y, width*4, y_off_x, y_off_y);

      //Fractional chroma U
      extend_borders(xpos>>1, ypos>>1, (mv[0]>>2)>>1, (mv[1]>>2)>>1, encoder_state->tile->lcu_offset_x * (LCU_WIDTH>>1), encoder_state->tile->lcu_offset_y * (LCU_WIDTH>>1),
          ref->u, ref->width>>1, ref->height>>1, FILTER_SIZE_C, width_c, width_c, octpel_src_u);

      filter_inter_octpel_chroma(encoder_state->encoder_control, octpel_src_off_u, width_c+FILTER_SIZE_C, width_c,
                                 width_c, octpel_dst_u, width_c*8, c_off_x, c_off_y);

      //Fractional chroma V
      extend_borders(xpos>>1, ypos>>1, (mv[0]>>2)>>1, (mv[1]>>2)>>1, encoder_state->tile->lcu_offset_x * (LCU_WIDTH>>1), encoder_state->tile->lcu_offset_y * (LCU_WIDTH>>1),
          ref->v, ref->width>>1, ref->height>>1, FILTER_SIZE_C, width_c, width_c, octpel_src_v);

      filter_inter_octpel_chroma(encoder_state->encoder_control, octpel_src_off_v, width_c+FILTER_SIZE_C, width_c,
                   width_c, octpel_dst_v, width_c*8, c_off_x, c_off_y);

      //Sample fractional pixels for luma
      for(y = 0; y < width; ++y) {
        int y_in_lcu = ((y+ypos) & ((LCU_WIDTH)-1));
        int qpel_y = y*4+y_off_y;
        for(x = 0; x < width; ++x) {
          int x_in_lcu = ((x+xpos) & ((LCU_WIDTH)-1));
          int qpel_x = x*4+y_off_x;
          lcu->rec.y[y_in_lcu * LCU_WIDTH + x_in_lcu] = (pixel)qpel_dst_y[qpel_y*(width*4)+qpel_x];
        }
      }
      //Sample fractional pixels for chroma
      for(y = 0; y < width_c; ++y) {
        int y_in_lcu = ((y+(ypos>>1)) & ((LCU_WIDTH>>1)-1));
{'fraction_non_alphanumeric': 0.1544279505559632, 'fraction_numerical': 0.025963763616865157, 'mean_word_length': 3.640649554740702, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 327, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2425101', 'n_tokens_mistral': 7269, 'n_tokens_neox': 6919, 'n_words': 1564}