source: 3DVCSoftware/branches/0.3-nokia/source/Lib/TLibCommon/TComPicYuv.cpp @ 122

Last change on this file since 122 was 17, checked in by hschwarz, 13 years ago

fix for DMM with non-10-bit processing

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