⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 img_luma.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*!
*************************************************************************************
* \file img_luma.c
*
* \brief
*    Luma interpolation functions
*
* \author
*    Main contributors (see contributors.h for copyright, address and affiliation details)
*      - Alexis Michael Tourapis <alexis.tourapis@dolby.com>
*      - Athanasios Leontaris    <aleon@dolby.com>
*
*************************************************************************************
*/

#include "contributors.h"

#include <limits.h>

#include "global.h"
#include "image.h"
#include "img_luma.h"
#include "memalloc.h"

const int ONE_FOURTH_TAP[2][3] =
{
  {20, -5, 1},  // AVC Interpolation taps
  {20,-4, 0},   // Experimental - not valid
};

/*!
 ************************************************************************
 * \brief
 *    Creates the 4x4 = 16 images that contain quarter-pel samples
 *    sub-sampled at different spatial orientations;
 *    enables more efficient implementation
 *
 * \param s
 *    pointer to StorablePicture structure
 s************************************************************************
 */
void getSubImagesLuma( StorablePicture *s )
{
  imgpel  **p_curr_img = s->p_curr_img;
  imgpel ****cImgSub   = s->p_curr_img_sub;

  //  0  1  2  3
  //  4  5  6  7
  //  8  9 10 11
  // 12 13 14 15

  //// INTEGER PEL POSITIONS ////

  // sub-image 0 [0][0]
  // simply copy the integer pels
  getSubImageInteger( s, cImgSub[0][0], p_curr_img);

  //// HALF-PEL POSITIONS: SIX-TAP FILTER ////

  // sub-image 2 [0][2]
  // HOR interpolate (six-tap) sub-image [0][0]
  getHorSubImageSixTap( s, cImgSub[0][2], cImgSub[0][0] );

  // sub-image 8 [2][0]
  // VER interpolate (six-tap) sub-image [0][0]
  getVerSubImageSixTap( s, cImgSub[2][0], cImgSub[0][0]);

  // sub-image 10 [2][2]
  // VER interpolate (six-tap) sub-image [0][2]
  getVerSubImageSixTapTmp( s, cImgSub[2][2], cImgSub[0][2]);

  //// QUARTER-PEL POSITIONS: BI-LINEAR INTERPOLATION ////

  // sub-image 1 [0][1]
  getSubImageBiLinear    ( s, cImgSub[0][1], cImgSub[0][0], cImgSub[0][2]);
  // sub-image 4 [1][0]
  getSubImageBiLinear    ( s, cImgSub[1][0], cImgSub[0][0], cImgSub[2][0]);
  // sub-image 5 [1][1]
  getSubImageBiLinear    ( s, cImgSub[1][1], cImgSub[0][2], cImgSub[2][0]);
  // sub-image 6 [1][2]
  getSubImageBiLinear    ( s, cImgSub[1][2], cImgSub[0][2], cImgSub[2][2]);
  // sub-image 9 [2][1]
  getSubImageBiLinear    ( s, cImgSub[2][1], cImgSub[2][0], cImgSub[2][2]);

  // sub-image 3  [0][3]
  getHorSubImageBiLinear ( s, cImgSub[0][3], cImgSub[0][2], cImgSub[0][0]);
  // sub-image 7  [1][3]
  getHorSubImageBiLinear ( s, cImgSub[1][3], cImgSub[0][2], cImgSub[2][0]);
  // sub-image 11 [2][3]
  getHorSubImageBiLinear ( s, cImgSub[2][3], cImgSub[2][2], cImgSub[2][0]);

  // sub-image 12 [3][0]
  getVerSubImageBiLinear ( s, cImgSub[3][0], cImgSub[2][0], cImgSub[0][0]);
  // sub-image 13 [3][1]
  getVerSubImageBiLinear ( s, cImgSub[3][1], cImgSub[2][0], cImgSub[0][2]);
  // sub-image 14 [3][2]
  getVerSubImageBiLinear ( s, cImgSub[3][2], cImgSub[2][2], cImgSub[0][2]);

  // sub-image 15 [3][3]
  getDiagSubImageBiLinear( s, cImgSub[3][3], cImgSub[0][2], cImgSub[2][0]);
}


/*!
 ************************************************************************
 * \brief
 *    Copy Integer Samples to image [0][0]
 *
 * \param s
 *    pointer to StorablePicture structure
 * \param dstImg
 *    destination image
 * \param srcImg
 *    source image
 ************************************************************************
 */
void getSubImageInteger( StorablePicture *s, imgpel **dstImg, imgpel **srcImg)
{
  int i, j;
  int size_x_minus1 = s->size_x - 1;

  static imgpel *wBufSrc, *wBufDst;

  // Copy top line
  wBufDst = &( dstImg[0][0] ); 
  wBufSrc = srcImg[0];
  // left IMG_PAD_SIZE
  for (i = 0; i < IMG_PAD_SIZE; i++)
    *(wBufDst++) = wBufSrc[0];
  // center 0-(s->size_x)
  memcpy(wBufDst, wBufSrc, s->size_x * sizeof(imgpel));
  wBufDst += s->size_x;
  // right IMG_PAD_SIZE
  for (i = 0; i < IMG_PAD_SIZE; i++)
    *(wBufDst++) = wBufSrc[size_x_minus1];

  // Now copy remaining pad lines
  for (j = 1; j < IMG_PAD_SIZE + 1; j++)
  {
    memcpy(dstImg[j], dstImg[j - 1], s->size_x_padded * sizeof(imgpel));
  }

  for (j = 1; j < s->size_y; j++)
  {    
    wBufDst = &( dstImg[j + IMG_PAD_SIZE][0] ); // 4:4:4 independent mode
    wBufSrc = srcImg[j];
    // left IMG_PAD_SIZE
    for (i = 0; i < IMG_PAD_SIZE; i++)
      *(wBufDst++) = wBufSrc[0];
    // center 0-(s->size_x)
    memcpy(wBufDst, wBufSrc, s->size_x * sizeof(imgpel));
    wBufDst += s->size_x;
    // right IMG_PAD_SIZE
    for (i = 0; i < IMG_PAD_SIZE; i++)
      *(wBufDst++) = wBufSrc[size_x_minus1];
  }

  // Replicate bottom pad lines
  for (j = s->size_y + IMG_PAD_SIZE; j < s->size_y_padded; j++)
  {    
    memcpy(dstImg[j], dstImg[j - 1], s->size_x_padded * sizeof(imgpel));
  }
}

/*!
 ************************************************************************
 * \brief
 *    Does _horizontal_ interpolation using the SIX TAP filters
 *
 * \param s
 *    pointer to StorablePicture structure
 * \param dstImg
 *    destination image
 * \param srcImg
 *    source image
 ************************************************************************
 */
void getHorSubImageSixTap( StorablePicture *s, imgpel **dstImg, imgpel **srcImg)
{
  int is, jpad, ipad;
  int ypadded_size = s->size_y_padded;
  int xpadded_size = s->size_x_padded;

  static imgpel *wBufSrc, *wBufDst;
  static imgpel *srcImgA, *srcImgB, *srcImgC, *srcImgD, *srcImgE, *srcImgF;
  static int *iBufDst;
  const int tap0 = ONE_FOURTH_TAP[0][0];
  const int tap1 = ONE_FOURTH_TAP[0][1];
  const int tap2 = ONE_FOURTH_TAP[0][2];

  for (jpad = 0; jpad < ypadded_size; jpad++)
  {
    wBufSrc = srcImg[jpad];     // 4:4:4 independent mode
    wBufDst = dstImg[jpad];     // 4:4:4 independent mode
    iBufDst = imgY_sub_tmp[jpad];

    srcImgA = &wBufSrc[0];
    srcImgB = &wBufSrc[0];      
    srcImgC = &wBufSrc[0];
    srcImgD = &wBufSrc[1];
    srcImgE = &wBufSrc[2];
    srcImgF = &wBufSrc[3];

    // left padded area
    is =
      (tap0 * (*srcImgA++ + *srcImgD++) +
      tap1 *  (*srcImgB   + *srcImgE++) +
      tap2 *  (*srcImgC   + *srcImgF++));

    *iBufDst++ =  is;
    *wBufDst++ = (imgpel) iClip1 ( img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );      

    is =
      (tap0 * (*srcImgA++ + *srcImgD++) +
      tap1 *  (*srcImgB++ + *srcImgE++) +
      tap2 *  (*srcImgC   + *srcImgF++));

    *iBufDst++ =  is;
    *wBufDst++ = (imgpel) iClip1 ( img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );      

    // center
    for (ipad = 2; ipad < xpadded_size - 4; ipad++)
    {
      is =
        (tap0 * (*srcImgA++ + *srcImgD++) +
        tap1 *  (*srcImgB++ + *srcImgE++) +
        tap2 *  (*srcImgC++ + *srcImgF++));

      *iBufDst++ =  is;
      *wBufDst++ = (imgpel) iClip1 ( img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );      
    }

    is = (
      tap0 * (*srcImgA++ + *srcImgD++) +
      tap1 * (*srcImgB++ + *srcImgE++) +
      tap2 * (*srcImgC++ + *srcImgF  ));

    *iBufDst++ =  is;
    *wBufDst++ = (imgpel) iClip1 ( img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );      

    // right padded area
    is = (
      tap0 * (*srcImgA++ + *srcImgD++) +
      tap1 * (*srcImgB++ + *srcImgE) +
      tap2 * (*srcImgC++ + *srcImgF));

    *iBufDst++ =  is;
    *wBufDst++ = (imgpel) iClip1 ( img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );      

    is = (
      tap0 * (*srcImgA++ + *srcImgD) +
      tap1 * (*srcImgB++ + *srcImgE) +
      tap2 * (*srcImgC++ + *srcImgF));

    *iBufDst++ =  is;
    *wBufDst++ = (imgpel) iClip1 ( img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );      

    is = (
      tap0 * (*srcImgA + *srcImgD) +
      tap1 * (*srcImgB + *srcImgE) +
      tap2 * (*srcImgC + *srcImgF));

    *iBufDst =  is;
    *wBufDst = (imgpel) iClip1 ( img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );      

  }
}


/*!
 ************************************************************************
 * \brief
 *    Does _vertical_ interpolation using the SIX TAP filters
 *
 * \param s
 *    pointer to StorablePicture structure
 * \param dstImg
 *    pointer to target image
 * \param srcImg
 *    pointer to source image
 ************************************************************************
 */
void getVerSubImageSixTap( StorablePicture *s, imgpel **dstImg, imgpel **srcImg)
{
  int is, jpad, ipad;
  int ypadded_size = s->size_y_padded;
  int xpadded_size = s->size_x_padded;
  int maxy = ypadded_size - 1;

  static imgpel *wxLineDst;
  static imgpel *srcImgA, *srcImgB, *srcImgC, *srcImgD, *srcImgE, *srcImgF;
  const int tap0 = ONE_FOURTH_TAP[0][0];
  const int tap1 = ONE_FOURTH_TAP[0][1];
  const int tap2 = ONE_FOURTH_TAP[0][2];

  // branches within the j loop
  // top
  for (jpad = 0; jpad < 2; jpad++)
  {
    wxLineDst = dstImg[jpad];
    srcImgA = srcImg[jpad ];
    srcImgB = srcImg[0];      
    srcImgC = srcImg[0];
    srcImgD = srcImg[jpad + 1];
    srcImgE = srcImg[jpad + 2];
    srcImgF = srcImg[jpad + 3];
    for (ipad = 0; ipad < xpadded_size; ipad++)
    {
      is =
        (tap0 * (*srcImgA++ + *srcImgD++) +
        tap1 *  (*srcImgB++ + *srcImgE++) +
        tap2 *  (*srcImgC++ + *srcImgF++));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -