source: 3DVCSoftware/branches/0.3-poznan-univ/source/Lib/TLibCommon/TComPicYuv.cpp @ 1417

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

Adjustment for FlexCO, and high-level syntax improvement.

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