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

📄 img_luma.c

📁 This program can encode the YUV vdieo format to H.264 and decode it.
💻 C
📖 第 1 页 / 共 2 页
字号:

/*!
*************************************************************************************
* \file img_luma.c
*
* \brief
*    Luma interpolation functions
*
* \author
*    Main contributors (see contributors.h for copyright, address and affiliation details)
*      - Athanasios Leontaris    <aleon@dolby.com>
*      - Alexis Michael Tourapis <alexis.tourapis@dolby.com>
*
*************************************************************************************
*/

#include "contributors.h"

#include <stdlib.h>
#include <memory.h>
#include <limits.h>

#include "global.h"
#include "image.h"
#include "img_luma.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 )
{
  int i, j;
  int jj, jpad;

  imgpel  **imgY = s->imgY;
  int size_x_minus1 = s->size_x - 1;
  int size_y_minus1 = s->size_y - 1;

  imgpel *wBufDst, *wBufSrc;

  if( IS_INDEPENDENT(input) )
  {
    switch( s->colour_plane_id ){
    default:
    case    0:
      imgY = s->imgY;
      break;
    case    1:
      imgY = s->imgUV[0];
      break;
    case    2:
      imgY = s->imgUV[1];
      break;
	}
 	s->curr_imgY_sub = s->p_imgY_sub[s->colour_plane_id];
  }
  else
  {
    s->curr_imgY_sub = s->imgY_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
  for (j = -IMG_PAD_SIZE; j < s->size_y + IMG_PAD_SIZE; j++)
  {
    jj = iClip3(0, size_y_minus1, j);
    jpad = j + IMG_PAD_SIZE;
    wBufDst = &( s->curr_imgY_sub[0][0][jpad][IMG_PAD_SIZE] ); // 4:4:4 independent mode
    wBufSrc = imgY[jj];
    // left IMG_PAD_SIZE
    for (i = -IMG_PAD_SIZE; i < 0; i++)
    {
      wBufDst[i] = wBufSrc[0];
    }
    // right IMG_PAD_SIZE
    for (i = s->size_x; i < s->size_x + IMG_PAD_SIZE; i++)
    {
      wBufDst[i] = wBufSrc[size_x_minus1];
    }
    // center 0-(s->size_x)
    memcpy(wBufDst, wBufSrc, s->size_x * sizeof(imgpel));
  }

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

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

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

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

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

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

  // sub-image 4 [1][0]
  getVerSubImageBiLinear( s, 1, 0, 0, 0, 2, 0,  0 );
  // sub-image 6 [1][2]
  getVerSubImageBiLinear( s, 1, 2, 0, 2, 2, 2,  0 );

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

  // sub-image 5 [1][1]
  getDiagSubImageBiLinear( s, 1, 1, 0, 2, 2, 0,  0, 0, 0, 0 );
  // sub-image 7 [1][3]
  getDiagSubImageBiLinear( s, 1, 3, 0, 2, 2, 0,  0, 0, 0, 1 );
  // sub-image 13 [3][1]
  getDiagSubImageBiLinear( s, 3, 1, 2, 0, 0, 2,  0, 0, 1, 0 );
  // sub-image 15 [3][3]
  getDiagSubImageBiLinear( s, 3, 3, 0, 2, 2, 0,  1, 0, 0, 1 );
}


/*!
 ************************************************************************
 * \brief
 *    Does _horizontal_ interpolation using the SIX TAP filters
 *
 * \param s
 *    pointer to StorablePicture structure
 * \param dst_y
 *    vertical index to sub-image being generated
 * \param dst_x
 *    horizontal index to sub-image being generated
 * \param src_y
 *    vertical index to source sub-image
 * \param src_x
 *    horizontal index to source sub-image
 ************************************************************************
 */
void getHorSubImageSixTap( StorablePicture *s, int dst_y, int dst_x, int src_y, int src_x )
{
  int is;
  int jpad;
  int ipad;
  int ypadded_size = s->size_y + 2 * IMG_PAD_SIZE;
  int xpadded_size = s->size_x + 2 * IMG_PAD_SIZE;
  int maxx = xpadded_size - 1;

  imgpel *wBufSrc, *wBufDst;
  int *iBufDst;
  int tap0 = ONE_FOURTH_TAP[0][0];
  int tap1 = ONE_FOURTH_TAP[0][1];
  int tap2 = ONE_FOURTH_TAP[0][2];

  for (jpad = 0; jpad < ypadded_size; jpad++)
  {
    wBufSrc = s->curr_imgY_sub[src_y][src_x][jpad];	// 4:4:4 independent mode
    wBufDst = s->curr_imgY_sub[dst_y][dst_x][jpad]; // 4:4:4 independent mode
    iBufDst = imgY_sub_tmp[jpad];

    // left padded area
    for (ipad = 0; ipad < 2; ipad++)
    {
      is =
        (tap0 * (wBufSrc[ipad]               + wBufSrc[ipad + 1]) +
        tap1  * (wBufSrc[imax (0, ipad - 1)] + wBufSrc[ipad + 2]) +
        tap2  * (wBufSrc[imax (0, ipad - 2)] + wBufSrc[ipad + 3]));

      wBufDst[ipad] = (imgpel) iClip3 (0, img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );
      iBufDst[ipad] =  is;
    }
    // center
    for (ipad = 2; ipad < xpadded_size - 3; ipad++)
    {
      is =
        (tap0 * (wBufSrc[ipad]     + wBufSrc[ipad + 1]) +
        tap1  * (wBufSrc[ipad - 1] + wBufSrc[ipad + 2]) +
        tap2  * (wBufSrc[ipad - 2] + wBufSrc[ipad + 3]));

      wBufDst[ipad] = (imgpel) iClip3 (0, img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );
      iBufDst[ipad] =  is;
    }
    // right padded area
    for (ipad = xpadded_size - 3; ipad < xpadded_size; ipad++)
    {
      is =
        (tap0 * (wBufSrc[ipad]     + wBufSrc[imin (maxx, ipad + 1)]) +
        tap1  * (wBufSrc[ipad - 1] + wBufSrc[imin (maxx, ipad + 2)]) +
        tap2  * (wBufSrc[ipad - 2] + wBufSrc[imin (maxx, ipad + 3)]));

      wBufDst[ipad] = (imgpel) iClip3 (0, img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );
      iBufDst[ipad] =  is;
    }
  }
}


/*!
 ************************************************************************
 * \brief
 *    Does _vertical_ interpolation using the SIX TAP filters
 *
 * \param s
 *    pointer to StorablePicture structure
 * \param dst_y
 *    vertical index to sub-image being generated
 * \param dst_x
 *    horizontal index to sub-image being generated
 * \param src_y
 *    vertical index to source sub-image
 * \param src_x
 *    horizontal index to source sub-image
 * \param use_stored_int
 *    use stored shifted integer version of picture to temporary array for
 *    increased fidelity during application of the six tap filter
 ************************************************************************
 */
void getVerSubImageSixTap( StorablePicture *s, int dst_y, int dst_x, int src_y, int src_x, int use_stored_int )
{
  int is;
  int jpad;
  int jlow1, jlow2, jhigh1, jhigh2, jhigh3;
  int ipad;
  int ypadded_size = s->size_y + 2 * IMG_PAD_SIZE;
  int xpadded_size = s->size_x + 2 * IMG_PAD_SIZE;
  int maxy = ypadded_size - 1;

  imgpel **wxBufSrc, **wxBufDst, *wxLineDst;
  int tap0 = ONE_FOURTH_TAP[0][0];
  int tap1 = ONE_FOURTH_TAP[0][1];
  int tap2 = ONE_FOURTH_TAP[0][2];

  wxBufSrc = s->curr_imgY_sub[src_y][src_x]; // 4:4:4 independent mode
  wxBufDst = s->curr_imgY_sub[dst_y][dst_x]; // 4:4:4 independent mode

  if ( !use_stored_int ) { // causes code expansion but is better since we avoid too many
    // branches within the j loop
    // top
    for (jpad = 0; jpad < 2; jpad++)
    {
      wxLineDst = wxBufDst[jpad];
      jlow1  = imax (0, jpad - 1);
      jlow2  = imax (0, jpad - 2);
      jhigh1 = jpad + 1;
      jhigh2 = jpad + 2;
      jhigh3 = jpad + 3;
      for (ipad = 0; ipad < xpadded_size; ipad++)
      {
        is =
          (tap0 * (wxBufSrc[jpad ][ipad] + wxBufSrc[jhigh1][ipad]) +
          tap1 *  (wxBufSrc[jlow1][ipad] + wxBufSrc[jhigh2][ipad]) +
          tap2 *  (wxBufSrc[jlow2][ipad] + wxBufSrc[jhigh3][ipad]));

        wxLineDst[ipad] = (imgpel) iClip3 (0, img->max_imgpel_value, rshift_rnd_sf( is, 5 ) );
      }
    }
    // center
    for (jpad = 2; jpad < ypadded_size - 3; jpad++)
    {
      wxLineDst = wxBufDst[jpad];
      jlow1  = jpad - 1;
      jlow2  = jpad - 2;
      jhigh1 = jpad + 1;

⌨️ 快捷键说明

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