text: /******************************************************************************
  *
  * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************/
  /**
  *******************************************************************************
  * @file
  *  ihevc_weighted_pred.c
  *
  * @brief
  *  Contains function definitions for weighted prediction used in inter
  * prediction
  *
  * @author
  *  Srinivas T
  *
  * @par List of Functions:
  *   - ihevc_weighted_pred_uni()
  *   - ihevc_weighted_pred_bi()
  *   - ihevc_weighted_pred_bi_default()
  *   - ihevc_weighted_pred_chroma_uni()
  *   - ihevc_weighted_pred_chroma_bi()
  *   - ihevc_weighted_pred_chroma_bi_default()
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
  /*****************************************************************************/
  /* File Includes                                                             */
  /*****************************************************************************/
  #include "ihevc_typedefs.h"
  #include "ihevc_defs.h"
  #include "ihevc_macros.h"
  #include "ihevc_platform_macros.h"
  #include "ihevc_func_selector.h"
  
  #include "ihevc_inter_pred.h"
  
  /**
  *******************************************************************************
  *
  * @brief
  *  Does uni-weighted prediction on the array pointed by  pi2_src and stores
  * it at the location pointed by pi2_dst
  *
  * @par Description:
  *  dst = ( (src + lvl_shift) * wgt0 + (1 << (shift - 1)) )  >> shift +
  * offset
  *
  * @param[in] pi2_src
  *  Pointer to the source
  *
  * @param[out] pu1_dst
  *  Pointer to the destination
  *
  * @param[in] src_strd
  *  Source stride
  *
  * @param[in] dst_strd
  *  Destination stride
  *
  * @param[in] wgt0
  *  weight to be multiplied to the source
  *
  * @param[in] off0
  *  offset to be added after rounding and
  *
  * @param[in] shifting
  *
  *
  * @param[in] shift
  *  (14 Bit depth) + log2_weight_denominator
  *
  * @param[in] lvl_shift
  *  added before shift and offset
  *
  * @param[in] ht
  *  height of the source
  *
  * @param[in] wd
  *  width of the source
  *
  * @returns
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
  
  void ihevc_weighted_pred_uni(WORD16 *pi2_src,
                               UWORD8 *pu1_dst,
                               WORD32 src_strd,
                               WORD32 dst_strd,
                               WORD32 wgt0,
                               WORD32 off0,
                               WORD32 shift,
                               WORD32 lvl_shift,
                               WORD32 ht,
                               WORD32 wd)
  {
      WORD32 row, col;
      WORD32 i4_tmp;
  
      for(row = 0; row < ht; row++)
      {
          for(col = 0; col < wd; col++)
          {
              i4_tmp = (pi2_src[col] + lvl_shift) * wgt0;
              i4_tmp += 1 << (shift - 1);
              i4_tmp = (i4_tmp >> shift) + off0;
  
              pu1_dst[col] = CLIP_U8(i4_tmp);
          }
  
          pi2_src += src_strd;
          pu1_dst += dst_strd;
      }
  }
  //WEIGHTED_PRED_UNI
  
  /**
  *******************************************************************************
  *
  * @brief
  * Does chroma uni-weighted prediction on array pointed by pi2_src and stores
  * it at the location pointed by pi2_dst
  *
  * @par Description:
  *  dst = ( (src + lvl_shift) * wgt0 + (1 << (shift - 1)) )  >> shift +
  * offset
  *
  * @param[in] pi2_src
  *  Pointer to the source
  *
  * @param[out] pu1_dst
  *  Pointer to the destination
  *
  * @param[in] src_strd
  *  Source stride
  *
  * @param[in] dst_strd
  *  Destination stride
  *
  * @param[in] wgt0
  *  weight to be multiplied to the source
  *
  * @param[in] off0
  *  offset to be added after rounding and
  *
  * @param[in] shifting
  *
  *
  * @param[in] shift
  *  (14 Bit depth) + log2_weight_denominator
  *
  * @param[in] lvl_shift
  *  added before shift and offset
  *
  * @param[in] ht
  *  height of the source
  *
  * @param[in] wd
  *  width of the source (each colour component)
  *
  * @returns
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
  
  void ihevc_weighted_pred_chroma_uni(WORD16 *pi2_src,
                                      UWORD8 *pu1_dst,
                                      WORD32 src_strd,
                                      WORD32 dst_strd,
                                      WORD32 wgt0_cb,
                                      WORD32 wgt0_cr,
                                      WORD32 off0_cb,
                                      WORD32 off0_cr,
                                      WORD32 shift,
                                      WORD32 lvl_shift,
                                      WORD32 ht,
                                      WORD32 wd)
  {
      WORD32 row, col;
      WORD32 i4_tmp;
  
      for(row = 0; row < ht; row++)
      {
          for(col = 0; col < 2 * wd; col += 2)
          {
              i4_tmp = (pi2_src[col] + lvl_shift) * wgt0_cb;
              i4_tmp += 1 << (shift - 1);
              i4_tmp = (i4_tmp >> shift) + off0_cb;
  
              pu1_dst[col] = CLIP_U8(i4_tmp);
  
              i4_tmp = (pi2_src[col + 1] + lvl_shift) * wgt0_cr;
              i4_tmp += 1 << (shift - 1);
              i4_tmp = (i4_tmp >> shift) + off0_cr;
  
              pu1_dst[col + 1] = CLIP_U8(i4_tmp);
          }
  
          pi2_src += src_strd;
          pu1_dst += dst_strd;
      }
  }
  //WEIGHTED_PRED_CHROMA_UNI
  
  /**
  *******************************************************************************
  *
  * @brief
  *  Does bi-weighted prediction on the arrays pointed by  pi2_src1 and
  * pi2_src2 and stores it at location pointed  by pi2_dst
  *
  * @par Description:
  *  dst = ( (src1 + lvl_shift1)*wgt0 +  (src2 + lvl_shift2)*wgt1 +  (off0 +
  * off1 + 1) << (shift - 1) ) >> shift
  *
  * @param[in] pi2_src1
  *  Pointer to source 1
  *
  * @param[in] pi2_src2
  *  Pointer to source 2
  *
  * @param[out] pu1_dst
  *  Pointer to destination
  *
  * @param[in] src_strd1
  *  Source stride 1
  *
  * @param[in] src_strd2
  *  Source stride 2
  *
  * @param[in] dst_strd
  *  Destination stride
  *
  * @param[in] wgt0
  *  weight to be multiplied to source 1
  *
  * @param[in] off0
  *  offset 0
  *
  * @param[in] wgt1
  *  weight to be multiplied to source 2
  *
  * @param[in] off1
  *  offset 1
  *
  * @param[in] shift
  *  (14 Bit depth) + log2_weight_denominator
  *
  * @param[in] lvl_shift1
  *  added before shift and offset
  *
  * @param[in] lvl_shift2
  *  added before shift and offset
  *
  * @param[in] ht
  *  height of the source
  *
  * @param[in] wd
  *  width of the source
  *
  * @returns
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
  
  void ihevc_weighted_pred_bi(WORD16 *pi2_src1,
                              WORD16 *pi2_src2,
                              UWORD8 *pu1_dst,
                              WORD32 src_strd1,
                              WORD32 src_strd2,
                              WORD32 dst_strd,
                              WORD32 wgt0,
                              WORD32 off0,
                              WORD32 wgt1,
                              WORD32 off1,
                              WORD32 shift,
                              WORD32 lvl_shift1,
                              WORD32 lvl_shift2,
                              WORD32 ht,
                              WORD32 wd)
  {
      WORD32 row, col;
      WORD32 i4_tmp;
  
      for(row = 0; row < ht; row++)
      {
          for(col = 0; col < wd; col++)
          {
              i4_tmp = (pi2_src1[col] + lvl_shift1) * wgt0;
              i4_tmp += (pi2_src2[col] + lvl_shift2) * wgt1;
              i4_tmp += (off0 + off1 + 1) << (shift - 1);
  
              pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
          }
  
          pi2_src1 += src_strd1;
          pi2_src2 += src_strd2;
          pu1_dst += dst_strd;
      }
  }
  //WEIGHTED_PRED_BI
  
  /**
  *******************************************************************************
  *
  * @brief
  * Does chroma bi-weighted prediction on the arrays pointed by  pi2_src1 and
  * pi2_src2 and stores it at location pointed  by pi2_dst
  *
  * @par Description:
  *  dst = ( (src1 + lvl_shift1)*wgt0 +  (src2 + lvl_shift2)*wgt1 +  (off0 +
  * off1 + 1) << (shift - 1) ) >> shift
  *
  * @param[in] pi2_src1
  *  Pointer to source 1
  *
  * @param[in] pi2_src2
  *  Pointer to source 2
  *
  * @param[out] pu1_dst
  *  Pointer to destination
  *
  * @param[in] src_strd1
  *  Source stride 1
  *
  * @param[in] src_strd2
  *  Source stride 2
  *
  * @param[in] dst_strd
  *  Destination stride
  *
  * @param[in] wgt0
  *  weight to be multiplied to source 1
  *
  * @param[in] off0
  *  offset 0
  *
  * @param[in] wgt1
  *  weight to be multiplied to source 2
  *
  * @param[in] off1
  *  offset 1
  *
  * @param[in] shift
  *  (14 Bit depth) + log2_weight_denominator
  *
  * @param[in] lvl_shift1
  *  added before shift and offset
  *
  * @param[in] lvl_shift2
  *  added before shift and offset
  *
  * @param[in] ht
  *  height of the source
  *
  * @param[in] wd
  *  width of the source (each colour component)
  *
  * @returns
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
  
  void ihevc_weighted_pred_chroma_bi(WORD16 *pi2_src1,
                                     WORD16 *pi2_src2,
                                     UWORD8 *pu1_dst,
                                     WORD32 src_strd1,
                                     WORD32 src_strd2,
                                     WORD32 dst_strd,
                                     WORD32 wgt0_cb,
                                     WORD32 wgt0_cr,
                                     WORD32 off0_cb,
                                     WORD32 off0_cr,
                                     WORD32 wgt1_cb,
                                     WORD32 wgt1_cr,
                                     WORD32 off1_cb,
                                     WORD32 off1_cr,
                                     WORD32 shift,
                                     WORD32 lvl_shift1,
                                     WORD32 lvl_shift2,
                                     WORD32 ht,
                                     WORD32 wd)
  {
      WORD32 row, col;
      WORD32 i4_tmp;
  
      for(row = 0; row < ht; row++)
      {
          for(col = 0; col < 2 * wd; col += 2)
          {
              i4_tmp = (pi2_src1[col] + lvl_shift1) * wgt0_cb;
              i4_tmp += (pi2_src2[col] + lvl_shift2) * wgt1_cb;
              i4_tmp += (off0_cb + off1_cb + 1) << (shift - 1);
  
              pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
  
              i4_tmp = (pi2_src1[col + 1] + lvl_shift1) * wgt0_cr;
              i4_tmp += (pi2_src2[col + 1] + lvl_shift2) * wgt1_cr;
              i4_tmp += (off0_cr + off1_cr + 1) << (shift - 1);
  
              pu1_dst[col + 1] = CLIP_U8(i4_tmp >> shift);
          }
  
          pi2_src1 += src_strd1;
          pi2_src2 += src_strd2;
          pu1_dst += dst_strd;
      }
  }
  //WEIGHTED_PRED_CHROMA_BI
  
  /**
  *******************************************************************************
  *
  * @brief
  *  Does default bi-weighted prediction on the arrays pointed by pi2_src1 and
  * pi2_src2 and stores it at location  pointed by pi2_dst
  *
  * @par Description:
  *  dst = ( (src1 + lvl_shift1) +  (src2 + lvl_shift2) +  1 << (shift - 1) )
  * >> shift  where shift = 15 - BitDepth
  *
  * @param[in] pi2_src1
  *  Pointer to source 1
  *
  * @param[in] pi2_src2
  *  Pointer to source 2
  *
  * @param[out] pu1_dst
  *  Pointer to destination
  *
  * @param[in] src_strd1
  *  Source stride 1
  *
  * @param[in] src_strd2
  *  Source stride 2
  *
  * @param[in] dst_strd
  *  Destination stride
  *
  * @param[in] lvl_shift1
  *  added before shift and offset
  *
  * @param[in] lvl_shift2
  *  added before shift and offset
  *
  * @param[in] ht
  *  height of the source
  *
  * @param[in] wd
  *  width of the source
  *
  * @returns
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
  
  void ihevc_weighted_pred_bi_default(WORD16 *pi2_src1,
                                      WORD16 *pi2_src2,
                                      UWORD8 *pu1_dst,
                                      WORD32 src_strd1,
                                      WORD32 src_strd2,
                                      WORD32 dst_strd,
                                      WORD32 lvl_shift1,
                                      WORD32 lvl_shift2,
                                      WORD32 ht,
                                      WORD32 wd)
  {
      WORD32 row, col;
      WORD32 i4_tmp;
      WORD32 shift;
  
      shift = SHIFT_14_MINUS_BIT_DEPTH + 1;
      for(row = 0; row < ht; row++)
      {
          for(col = 0; col < wd; col++)
          {
              i4_tmp = pi2_src1[col] + lvl_shift1;
              i4_tmp += pi2_src2[col] + lvl_shift2;
              i4_tmp += 1 << (shift - 1);
  
              pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
          }
  
          pi2_src1 += src_strd1;
          pi2_src2 += src_strd2;
          pu1_dst += dst_strd;
      }
  }
  //WEIGHTED_PRED_BI_DEFAULT
  
  /**
  *******************************************************************************
  *
  * @brief
  *  Does chroma default bi-weighted prediction on arrays pointed by pi2_src1 and
  * pi2_src2 and stores it at location  pointed by pi2_dst
  *
  * @par Description:
  *  dst = ( (src1 + lvl_shift1) +  (src2 + lvl_shift2) +  1 << (shift - 1) )
  * >> shift  where shift = 15 - BitDepth
  *
  * @param[in] pi2_src1
  *  Pointer to source 1
  *
  * @param[in] pi2_src2
  *  Pointer to source 2
  *
  * @param[out] pu1_dst
  *  Pointer to destination
  *
  * @param[in] src_strd1
  *  Source stride 1
  *
  * @param[in] src_strd2
  *  Source stride 2
  *
  * @param[in] dst_strd
  *  Destination stride
  *
  * @param[in] lvl_shift1
  *  added before shift and offset
  *
  * @param[in] lvl_shift2
  *  added before shift and offset
  *
  * @param[in] ht
  *  height of the source
  *
  * @param[in] wd
  *  width of the source (each colour component)
  *
  * @returns
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
  
  void ihevc_weighted_pred_chroma_bi_default(WORD16 *pi2_src1,
                                             WORD16 *pi2_src2,
                                             UWORD8 *pu1_dst,
                                             WORD32 src_strd1,
                                             WORD32 src_strd2,
                                             WORD32 dst_strd,
                                             WORD32 lvl_shift1,
                                             WORD32 lvl_shift2,
                                             WORD32 ht,
                                             WORD32 wd)
  {
      WORD32 row, col;
      WORD32 i4_tmp;
      WORD32 shift;
  
      shift = SHIFT_14_MINUS_BIT_DEPTH + 1;
      for(row = 0; row < ht; row++)
      {
          for(col = 0; col < 2 * wd; col++)
          {
              i4_tmp = pi2_src1[col] + lvl_shift1;
              i4_tmp += pi2_src2[col] + lvl_shift2;
              i4_tmp += 1 << (shift - 1);
  
              pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
          }
  
          pi2_src1 += src_strd1;
          pi2_src2 += src_strd2;
          pu1_dst += dst_strd;
      }
  }
  //WEIGHTED_PRED_CHROMA_BI_DEFAULT
  