source: 3DVCSoftware/branches/0.2-poznan-univ/source/Lib/TLibCommon/TComPicYuv.cpp @ 28

Last change on this file since 28 was 12, checked in by poznan-univ, 13 years ago

Poznan Tools

  • Depth base motion vector prediction
  • Property svn:eol-style set to native
File size: 13.9 KB
Line 
1
2
3/** \file     TComPicYuv.cpp
4    \brief    picture YUV buffer class
5*/
6
7#include <cstdlib>
8#include <assert.h>
9#include <memory.h>
10#include <math.h>
11
12#ifdef __APPLE__
13#include <malloc/malloc.h>
14#else
15#include <malloc.h>
16#endif
17
18#include "TComPicYuv.h"
19
20
21TComPicYuv::TComPicYuv()
22{
23  m_apiPicBufY      = NULL;   // Buffer (including margin)
24  m_apiPicBufU      = NULL;
25  m_apiPicBufV      = NULL;
26 
27  m_piPicOrgY       = NULL;    // m_apiPicBufY + m_iMarginLuma*getStride() + m_iMarginLuma
28  m_piPicOrgU       = NULL;
29  m_piPicOrgV       = NULL;
30 
31  m_bIsBorderExtended = false;
32}
33
34TComPicYuv::~TComPicYuv()
35{
36}
37
38Void TComPicYuv::create( Int iPicWidth, Int iPicHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth )
39{
40  m_iPicWidth       = iPicWidth;
41  m_iPicHeight      = iPicHeight;
42 
43  // --> After config finished!
44  m_iCuWidth        = uiMaxCUWidth;
45  m_iCuHeight       = uiMaxCUHeight;
46  m_uiMaxCuDepth    = uiMaxCUDepth;
47 
48  m_iNumCuInWidth   = m_iPicWidth / m_iCuWidth;
49  m_iNumCuInWidth  += ( m_iPicWidth % m_iCuWidth ) ? 1 : 0;
50 
51  m_iBaseUnitWidth  = uiMaxCUWidth  >> uiMaxCUDepth;
52  m_iBaseUnitHeight = uiMaxCUHeight >> uiMaxCUDepth;
53 
54  m_iLumaMarginX    = g_uiMaxCUWidth  + 12; // up to 12-tap DIF
55  m_iLumaMarginY    = g_uiMaxCUHeight + 12; // up to 12-tap DIF
56 
57  m_iChromaMarginX  = m_iLumaMarginX>>1;
58  m_iChromaMarginY  = m_iLumaMarginY>>1;
59 
60  m_apiPicBufY      = (Pel*)xMalloc( Pel, ( m_iPicWidth       + (m_iLumaMarginX  <<1)) * ( m_iPicHeight       + (m_iLumaMarginY  <<1)));
61  m_apiPicBufU      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
62  m_apiPicBufV      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
63 
64  m_piPicOrgY       = m_apiPicBufY + m_iLumaMarginY   * getStride()  + m_iLumaMarginX;
65  m_piPicOrgU       = m_apiPicBufU + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
66  m_piPicOrgV       = m_apiPicBufV + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
67 
68  m_bIsBorderExtended = false;
69 
70  return;
71}
72
73Void TComPicYuv::destroy()
74{
75  m_piPicOrgY       = NULL;
76  m_piPicOrgU       = NULL;
77  m_piPicOrgV       = NULL;
78 
79  if( m_apiPicBufY ){ xFree( m_apiPicBufY );    m_apiPicBufY = NULL; }
80  if( m_apiPicBufU ){ xFree( m_apiPicBufU );    m_apiPicBufU = NULL; }
81  if( m_apiPicBufV ){ xFree( m_apiPicBufV );    m_apiPicBufV = NULL; }
82}
83
84Void TComPicYuv::createLuma( Int iPicWidth, Int iPicHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth )
85{
86  m_iPicWidth       = iPicWidth;
87  m_iPicHeight      = iPicHeight;
88 
89  // --> After config finished!
90  m_iCuWidth        = uiMaxCUWidth;
91  m_iCuHeight       = uiMaxCUHeight;
92  m_uiMaxCuDepth    = uiMaxCUDepth;
93 
94  m_iNumCuInWidth   = m_iPicWidth / m_iCuWidth;
95  m_iNumCuInWidth  += ( m_iPicWidth % m_iCuWidth ) ? 1 : 0;
96 
97  m_iBaseUnitWidth  = uiMaxCUWidth  >> uiMaxCUDepth;
98  m_iBaseUnitHeight = uiMaxCUHeight >> uiMaxCUDepth;
99 
100  m_iLumaMarginX    = g_uiMaxCUWidth  + 12; // up to 12-tap DIF
101  m_iLumaMarginY    = g_uiMaxCUHeight + 12; // up to 12-tap DIF
102 
103  m_apiPicBufY      = (Pel*)xMalloc( Pel, ( m_iPicWidth       + (m_iLumaMarginX  <<1)) * ( m_iPicHeight       + (m_iLumaMarginY  <<1)));
104  m_piPicOrgY       = m_apiPicBufY + m_iLumaMarginY   * getStride()  + m_iLumaMarginX;
105 
106  return;
107}
108
109Void TComPicYuv::destroyLuma()
110{
111  m_piPicOrgY       = NULL;
112 
113  if( m_apiPicBufY ){ xFree( m_apiPicBufY );    m_apiPicBufY = NULL; }
114}
115
116Pel*  TComPicYuv::getLumaAddr( int iCuAddr )
117{
118  Int iCuX = iCuAddr % m_iNumCuInWidth;
119  Int iCuY = iCuAddr / m_iNumCuInWidth;
120 
121  return ( m_piPicOrgY + iCuY*m_iCuHeight*getStride() + iCuX*m_iCuWidth );
122}
123
124Pel*  TComPicYuv::getLumaAddr( Int iCuAddr, Int uiAbsZorderIdx )
125{
126  Int iCuX           = iCuAddr % m_iNumCuInWidth;
127  Int iCuY           = iCuAddr / m_iNumCuInWidth;
128  Int iOffsetCu      = iCuY*m_iCuHeight*getStride() + iCuX*m_iCuWidth;
129 
130  Int iCuSizeInBases = m_iCuWidth / m_iBaseUnitWidth;
131  Int iRastPartIdx   = g_auiZscanToRaster[uiAbsZorderIdx];
132  Int iBaseX         = iRastPartIdx % iCuSizeInBases;
133  Int iBaseY         = iRastPartIdx / iCuSizeInBases;
134  Int iOffsetBase    = iBaseY*m_iBaseUnitHeight*getStride() + iBaseX*m_iBaseUnitWidth;
135 
136  return (m_piPicOrgY + iOffsetCu + iOffsetBase);
137}
138
139Pel*  TComPicYuv::getCbAddr( int iCuAddr )
140{
141  Int iCuX = iCuAddr % m_iNumCuInWidth;
142  Int iCuY = iCuAddr / m_iNumCuInWidth;
143 
144  return ( m_piPicOrgU + ( ( iCuY*m_iCuHeight*getCStride() + iCuX*m_iCuWidth )>>1 ) );
145}
146
147Pel*  TComPicYuv::getCbAddr( Int iCuAddr, Int uiAbsZorderIdx )
148{
149  Int iCuX           = iCuAddr % m_iNumCuInWidth;
150  Int iCuY           = iCuAddr / m_iNumCuInWidth;
151  Int iOffsetCu      = iCuY*m_iCuHeight*getCStride() + iCuX*m_iCuWidth;
152 
153  Int iCuSizeInBases = m_iCuWidth / m_iBaseUnitWidth;
154  Int iRastPartIdx   = g_auiZscanToRaster[uiAbsZorderIdx];
155  Int iBaseX         = iRastPartIdx % iCuSizeInBases;
156  Int iBaseY         = iRastPartIdx / iCuSizeInBases;
157  Int iOffsetBase    = iBaseY*m_iBaseUnitHeight*getCStride() + iBaseX*m_iBaseUnitWidth;
158 
159  return (m_piPicOrgU + ( ( iOffsetCu + iOffsetBase)>>1 ) );
160}
161
162Pel*  TComPicYuv::getCrAddr( int iCuAddr )
163{
164  Int iCuX = iCuAddr % m_iNumCuInWidth;
165  Int iCuY = iCuAddr / m_iNumCuInWidth;
166 
167  return ( m_piPicOrgV + ( ( iCuY*m_iCuHeight*getCStride() + iCuX*m_iCuWidth )>>1 ) );
168}
169
170Pel*  TComPicYuv::getCrAddr( Int iCuAddr, Int uiAbsZorderIdx )
171{
172  Int iCuX           = iCuAddr % m_iNumCuInWidth;
173  Int iCuY           = iCuAddr / m_iNumCuInWidth;
174  Int iOffsetCu      = iCuY*m_iCuHeight*getCStride() + iCuX*m_iCuWidth;
175 
176  Int iCuSizeInBases = m_iCuWidth / m_iBaseUnitWidth;
177  Int iRastPartIdx   = g_auiZscanToRaster[uiAbsZorderIdx];
178  Int iBaseX         = iRastPartIdx % iCuSizeInBases;
179  Int iBaseY         = iRastPartIdx / iCuSizeInBases;
180  Int iOffsetBase    = iBaseY*m_iBaseUnitHeight*getCStride() + iBaseX*m_iBaseUnitWidth;
181 
182  return (m_piPicOrgV + ( ( iOffsetCu + iOffsetBase)>>1 ) );
183}
184
185Void  TComPicYuv::copyToPic (TComPicYuv*  pcPicYuvDst)
186{
187  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
188  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
189 
190  ::memcpy ( pcPicYuvDst->getBufY(), m_apiPicBufY, sizeof (Pel) * ( m_iPicWidth       + (m_iLumaMarginX   << 1)) * ( m_iPicHeight       + (m_iLumaMarginY   << 1)) );
191  ::memcpy ( pcPicYuvDst->getBufU(), m_apiPicBufU, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
192  ::memcpy ( pcPicYuvDst->getBufV(), m_apiPicBufV, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
193  return;
194}
195
196Void  TComPicYuv::copyToPicLuma (TComPicYuv*  pcPicYuvDst)
197{
198  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
199  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
200 
201  ::memcpy ( pcPicYuvDst->getBufY(), m_apiPicBufY, sizeof (Pel) * ( m_iPicWidth       + (m_iLumaMarginX   << 1)) * ( m_iPicHeight       + (m_iLumaMarginY   << 1)) );
202  return;
203}
204
205Void  TComPicYuv::copyToPicCb (TComPicYuv*  pcPicYuvDst)
206{
207  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
208  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
209 
210  ::memcpy ( pcPicYuvDst->getBufU(), m_apiPicBufU, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
211  return;
212}
213
214Void  TComPicYuv::copyToPicCr (TComPicYuv*  pcPicYuvDst)
215{
216  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
217  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
218 
219  ::memcpy ( pcPicYuvDst->getBufV(), m_apiPicBufV, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
220  return;
221}
222
223
224Void TComPicYuv::getLumaMinMax( Int *pMin, Int *pMax )
225{
226  Pel*  piY   = getLumaAddr();
227  Int   iMin  = (1<<(g_uiBitDepth))-1;
228  Int   iMax  = 0;
229  Int   x, y;
230 
231  for ( y = 0; y < m_iPicHeight; y++ )
232  {
233    for ( x = 0; x < m_iPicWidth; x++ )
234    {
235      if ( piY[x] < iMin ) iMin = piY[x];
236      if ( piY[x] > iMax ) iMax = piY[x];
237    }
238    piY += getStride();
239  }
240 
241  *pMin = iMin;
242  *pMax = iMax;
243}
244
245Void TComPicYuv::extendPicBorder ()
246{
247  if ( m_bIsBorderExtended ) return;
248 
249  xExtendPicCompBorder( getLumaAddr(), getStride(),  getWidth(),      getHeight(),      m_iLumaMarginX,   m_iLumaMarginY   );
250  xExtendPicCompBorder( getCbAddr()  , getCStride(), getWidth() >> 1, getHeight() >> 1, m_iChromaMarginX, m_iChromaMarginY );
251  xExtendPicCompBorder( getCrAddr()  , getCStride(), getWidth() >> 1, getHeight() >> 1, m_iChromaMarginX, m_iChromaMarginY );
252 
253  m_bIsBorderExtended = true;
254}
255
256Void TComPicYuv::xExtendPicCompBorder  (Pel* piTxt, Int iStride, Int iWidth, Int iHeight, Int iMarginX, Int iMarginY)
257{
258  Int   x, y;
259  Pel*  pi;
260 
261  pi = piTxt;
262  for ( y = 0; y < iHeight; y++)
263  {
264    for ( x = 0; x < iMarginX; x++ )
265    {
266      pi[ -iMarginX + x ] = pi[0];
267      pi[    iWidth + x ] = pi[iWidth-1];
268    }
269    pi += iStride;
270  }
271 
272  pi -= (iStride + iMarginX);
273  for ( y = 0; y < iMarginY; y++ )
274  {
275    ::memcpy( pi + (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
276  }
277 
278  pi -= ((iHeight-1) * iStride);
279  for ( y = 0; y < iMarginY; y++ )
280  {
281    ::memcpy( pi - (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
282  }
283}
284
285
286Void TComPicYuv::dump (char* pFileName, Bool bAdd)
287{
288  FILE* pFile;
289  if (!bAdd)
290  {
291    pFile = fopen (pFileName, "wb");
292  }
293  else
294  {
295    pFile = fopen (pFileName, "ab");
296  }
297 
298  Int     shift = g_uiBitIncrement;
299  Int     offset = (shift>0)?(1<<(shift-1)):0;
300 
301  Int   x, y;
302  UChar uc;
303 
304  Pel*  piY   = getLumaAddr();
305  Pel*  piCb  = getCbAddr();
306  Pel*  piCr  = getCrAddr();
307 
308  Pel  iMax = ((1<<(g_uiBitDepth))-1);
309 
310  for ( y = 0; y < m_iPicHeight; y++ )
311  {
312    for ( x = 0; x < m_iPicWidth; x++ )
313    {
314      uc = (UChar)Clip3(0, iMax, (piY[x]+offset)>>shift);
315     
316      fwrite( &uc, sizeof(UChar), 1, pFile );
317    }
318    piY += getStride();
319  }
320 
321  for ( y = 0; y < m_iPicHeight >> 1; y++ )
322  {
323    for ( x = 0; x < m_iPicWidth >> 1; x++ )
324    {
325      uc = (UChar)Clip3(0, iMax, (piCb[x]+offset)>>shift);
326      fwrite( &uc, sizeof(UChar), 1, pFile );
327    }
328    piCb += getCStride();
329  }
330 
331  for ( y = 0; y < m_iPicHeight >> 1; y++ )
332  {
333    for ( x = 0; x < m_iPicWidth >> 1; x++ )
334    {
335      uc = (UChar)Clip3(0, iMax, (piCr[x]+offset)>>shift);
336      fwrite( &uc, sizeof(UChar), 1, pFile );
337    }
338    piCr += getCStride();
339  }
340 
341  fclose(pFile);
342}
343
344#if FIXED_ROUNDING_FRAME_MEMORY
345Void TComPicYuv::xFixedRoundingPic()
346{
347  Int   x, y;
348  Pel*  pRec    = getLumaAddr();
349  Int   iStride = getStride();
350  Int   iWidth  = getWidth();
351  Int   iHeight = getHeight();
352#if FULL_NBIT
353  Int   iOffset  = ((g_uiBitDepth-8)>0)?(1<<(g_uiBitDepth-8-1)):0;
354  Int   iMask   = (~0<<(g_uiBitDepth-8));
355  Int   iMaxBdi = g_uiBASE_MAX<<(g_uiBitDepth-8);
356#else
357  Int   iOffset  = (g_uiBitIncrement>0)?(1<<(g_uiBitIncrement-1)):0;
358  Int   iMask   = (~0<<g_uiBitIncrement);
359  Int   iMaxBdi = g_uiBASE_MAX<<g_uiBitIncrement;
360#endif
361
362  for( y = 0; y < iHeight; y++ )
363  {
364    for( x = 0; x < iWidth; x++ )
365    {
366#if IBDI_NOCLIP_RANGE
367      pRec[x] = ( pRec[x] + iOffset ) & iMask;
368#else
369      pRec[x] = ( pRec[x]+iOffset>iMaxBdi)? iMaxBdi : ((pRec[x]+iOffset) & iMask);
370#endif
371    }
372    pRec += iStride;
373  }
374
375  iHeight >>= 1;
376  iWidth  >>= 1;
377  iStride >>= 1;
378  pRec  = getCbAddr();
379
380  for( y = 0; y < iHeight; y++ )
381  {
382    for( x = 0; x < iWidth; x++ )
383    {
384#if IBDI_NOCLIP_RANGE
385      pRec[x] = ( pRec[x] + iOffset ) & iMask;
386#else
387      pRec[x] = ( pRec[x]+iOffset>iMaxBdi)? iMaxBdi : ((pRec[x]+iOffset) & iMask);
388#endif
389    }
390    pRec += iStride;
391  }
392
393  pRec  = getCrAddr();
394
395  for( y = 0; y < iHeight; y++ )
396  {
397    for( x = 0; x < iWidth; x++ )
398    {
399#if IBDI_NOCLIP_RANGE
400      pRec[x] = ( pRec[x] + iOffset ) & iMask;
401#else
402      pRec[x] = ( pRec[x]+iOffset>iMaxBdi)? iMaxBdi : ((pRec[x]+iOffset) & iMask);
403#endif
404    }
405    pRec += iStride;
406  }
407}
408#endif
409
410
411Void
412TComPicYuv::getTopLeftSamplePos( Int iCuAddr, Int iAbsZorderIdx, Int& riX, Int& riY )
413{
414  Int iRastPartIdx    = g_auiZscanToRaster[iAbsZorderIdx];
415  Int iCuSizeInBases  = m_iCuWidth   / m_iBaseUnitWidth;
416  Int iCuX            = iCuAddr      % m_iNumCuInWidth;
417  Int iCuY            = iCuAddr      / m_iNumCuInWidth;
418  Int iBaseX          = iRastPartIdx % iCuSizeInBases;
419  Int iBaseY          = iRastPartIdx / iCuSizeInBases;
420  riX                 = iCuX * m_iCuWidth  + iBaseX * m_iBaseUnitWidth;
421  riY                 = iCuY * m_iCuHeight + iBaseY * m_iBaseUnitHeight;
422}
423
424Void
425TComPicYuv::getCUAddrAndPartIdx( Int iX, Int iY, Int& riCuAddr, Int& riAbsZorderIdx )
426{
427  Int iCuX            = iX / m_iCuWidth;
428  Int iCuY            = iY / m_iCuHeight;
429  Int iBaseX          = ( iX - iCuX * m_iCuWidth  ) / m_iBaseUnitWidth;
430  Int iBaseY          = ( iY - iCuY * m_iCuHeight ) / m_iBaseUnitHeight;
431  Int iCuSizeInBases  = m_iCuWidth                  / m_iBaseUnitWidth;
432  riCuAddr            = iCuY   * m_iNumCuInWidth + iCuX;
433  Int iRastPartIdx    = iBaseY * iCuSizeInBases  + iBaseX;
434  riAbsZorderIdx      = g_auiRasterToZscan[ iRastPartIdx ];
435}
436
437Void TComPicYuv::setLumaTo( Pel pVal )
438{
439  xSetPels( getLumaAddr(), getStride(), getWidth(), getHeight() >> 1, pVal );
440}
441
442Void TComPicYuv::setChromaTo( Pel pVal )
443{
444  xSetPels( getCbAddr(), getCStride(), getWidth() >> 1, getHeight() >> 1, pVal ); 
445  xSetPels( getCrAddr(), getCStride(), getWidth() >> 1, getHeight() >> 1, pVal );
446}
447
448Void TComPicYuv::xSetPels( Pel* piPelSource , Int iSourceStride, Int iWidth, Int iHeight, Pel iVal )
449{
450  for (Int iYPos = 0; iYPos < iHeight; iYPos++)
451  {
452    for (Int iXPos = 0; iXPos < iWidth; iXPos++)
453    {
454      piPelSource[iXPos] = iVal; 
455    }
456    piPelSource += iSourceStride; 
457  }
458}
459
460#if POZNAN_NONLINEAR_DEPTH
461Void TComPicYuv::power(TComPicYuv *pcPicDst, Float p)
462{
463  Int           x,y;
464  TComPowerConverter powconv(p, g_uiBitIncrement, g_uiBitIncrement);
465
466  // Luma
467  Pel* pPelSrc = getLumaAddr();
468  Pel* pPelDst = pcPicDst->getLumaAddr();
469  for(y=0; y<m_iPicHeight; y++)
470        {
471    for(x=0; x<m_iPicWidth; x++)
472    {
473      pPelDst[x] = (Pel)( powconv(pPelSrc[x]) + 0.5);
474    }
475    pPelDst += pcPicDst->getStride();
476    pPelSrc += getStride();
477  }
478  // Chroma
479  copyToPicCb(pcPicDst);
480  copyToPicCr(pcPicDst);
481}
482#endif
Note: See TracBrowser for help on using the repository browser.