blob: e2a4ebca2a7d174c5291895cc52bb7aae9b0755f [file] [log] [blame]
/*!
*************************************************************************************
* \file img_chroma.c
*
* \brief
* Chroma 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 <limits.h>
#include "global.h"
#include "image.h"
#include "img_luma.h"
/*!
************************************************************************
* \brief
* Creates the 16 (YUV444), 32 (YUV422), or 64 (YUV420) sub-images that
* contain quarter-pel samples sub-sampled at different
* spatial orientationss;
* enables more efficient implementation
*
* \param s
* pointer to StorablePicture structure
s************************************************************************
*/
void getSubImagesChroma( StorablePicture *s )
{
int jpad, ipad, i, j, jj, ii_plus_one, jj_plus_one, uv, k, l;
int weight00, weight01, weight10, weight11;
int ypadded_size;
int xpadded_size;
int subimages_y, subimages_x, subx, suby;
int maxx, maxy;
int size_x_minus1;
int size_y_minus1;
// multiplier factor for index to account for UV sampling ratios
int mul_x, mul_y;
int mm, kk;
imgpel *wBufSrc0, *wBufSrc1, *wBufDst;
size_x_minus1 = s->size_x_cr - 1;
size_y_minus1 = s->size_y_cr - 1;
if ( img->yuv_format == YUV420 ) {
subimages_x = 8;
subimages_y = 8;
mul_x = mul_y = 1;
}
else if ( img->yuv_format == YUV422 ) {
subimages_x = 8;
subimages_y = 4;
mul_y = 2;
mul_x = 1;
}
else { // YUV444
subimages_x = 4;
subimages_y = 4;
mul_x = mul_y = 2;
}
xpadded_size = s->size_x_cr + 2*img_pad_size_uv_x;
ypadded_size = s->size_y_cr + 2*img_pad_size_uv_y;
maxx = xpadded_size - 1;
maxy = ypadded_size - 1;
// U or V
for ( uv = 0; uv < 2; uv++ )
{
for ( suby = 0, k = 0; suby < subimages_y; suby++, k += mul_y )
{
int m = (8 - k);
mm = m * 8;
kk = k * 8;
for ( subx = 0, l = 0; subx < subimages_x; subx++, l += mul_x )
{
weight00 = m * (8-l);
weight01 = m * l;
weight10 = k * (8-l);
weight11 = k * l;
for (j = -img_pad_size_uv_y, jpad = 0; j < ypadded_size - img_pad_size_uv_y; j++, jpad++)
{
jj = iClip3(0,size_y_minus1, j);
jj_plus_one = iClip3(0,size_y_minus1, j + 1);
wBufDst = &( s->imgUV_sub[uv][suby][subx][jpad][0] );
wBufSrc0 = s->imgUV[uv][jj ];
wBufSrc1 = s->imgUV[uv][jj_plus_one];
for (i = -img_pad_size_uv_x, ipad = 0; i < 0; i++, ipad++)
{
wBufDst[ipad] = (imgpel) rshift_rnd_sf(
mm * wBufSrc0[0] + kk * wBufSrc1[0], 6 );
}
for (i = 0; i < size_x_minus1; i++, ipad++)
{
ii_plus_one = i + 1;
wBufDst[ipad] = (imgpel) rshift_rnd_sf(
weight00 * wBufSrc0[i] + weight01 * wBufSrc0[ii_plus_one] +
weight10 * wBufSrc1[i] + weight11 * wBufSrc1[ii_plus_one], 6 );
}
for (i = size_x_minus1; i < xpadded_size - img_pad_size_uv_x; i++, ipad++)
{
wBufDst[ipad] = (imgpel) rshift_rnd_sf(
mm * wBufSrc0[size_x_minus1] + kk * wBufSrc1[size_x_minus1], 6 );
}
}
}
}
}
}