source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TCom3DAsymLUT.cpp @ 1263

Last change on this file since 1263 was 1216, checked in by seregin, 9 years ago

macro cleanup: R0179_CGS_SIZE_8x1x1

File size: 12.4 KB
RevLine 
[677]1#include <cstdio>
2#include <cstdlib>
3#include <cstring>
4#include <cmath>
5#include <algorithm>
6
7#include "TypeDef.h"
8#include "TCom3DAsymLUT.h"
9#include "TComPicYuv.h"
10
[1212]11#if CGS_3D_ASYMLUT
[677]12const Int TCom3DAsymLUT::m_nVertexIdxOffset[4][3] = { { 0 , 0 , 0 } , { 0 , 1 , 0 } , { 0 , 1 , 1 } , { 1 , 1 , 1 } };
13
14TCom3DAsymLUT::TCom3DAsymLUT()
15{
16  m_pCuboid = NULL;
17  m_nResQuanBit = 0;
[852]18#if R0164_CGS_LUT_BUGFIX_CHECK
[825]19  m_pCuboidExplicit = NULL;
[852]20  m_pCuboidFilled = NULL;
[825]21#endif
[677]22}
23
24TCom3DAsymLUT::~TCom3DAsymLUT()
25{
26  destroy();
27}
28
[1214]29Void TCom3DAsymLUT::create( Int nMaxOctantDepth, Int nInputBitDepth, Int nInputBitDepthC, Int nOutputBitDepth, Int nOutputBitDepthC, Int nMaxYPartNumLog2, Int nAdaptCThresholdU, Int nAdaptCThresholdV )
[677]30{
31  m_nMaxOctantDepth = nMaxOctantDepth;
32  m_nInputBitDepthY = nInputBitDepth;
33  m_nOutputBitDepthY = nOutputBitDepth;
34  m_nInputBitDepthC = nInputBitDepthC;
35  m_nOutputBitDepthC = nOutputBitDepthC;
36  m_nDeltaBitDepthC = m_nOutputBitDepthC - m_nInputBitDepthC;
37  m_nDeltaBitDepth = m_nOutputBitDepthY - m_nInputBitDepthY;
38  m_nMaxYPartNumLog2 = nMaxYPartNumLog2;
39  m_nMaxPartNumLog2 = 3 * m_nMaxOctantDepth + m_nMaxYPartNumLog2;
40
[1214]41  xUpdatePartitioning( nMaxOctantDepth, nMaxYPartNumLog2, nAdaptCThresholdU, nAdaptCThresholdV );
[677]42
43  m_nYSize = 1 << ( m_nMaxOctantDepth + m_nMaxYPartNumLog2 );
44  m_nUSize = 1 << m_nMaxOctantDepth;
45  m_nVSize = 1 << m_nMaxOctantDepth;
46  assert( m_nYSize > 0 && m_nUSize > 0 && m_nVSize > 0 );
47
48  if( m_pCuboid != NULL )
[815]49  {
[677]50    destroy();
[815]51  }
[677]52  xAllocate3DArray( m_pCuboid , m_nYSize , m_nUSize , m_nVSize );
[825]53
[852]54#if R0164_CGS_LUT_BUGFIX_CHECK
[825]55  xAllocate3DArray( m_pCuboidExplicit , m_nYSize , m_nUSize , m_nVSize );
[852]56  xAllocate3DArray( m_pCuboidFilled   , m_nYSize , m_nUSize , m_nVSize );
[825]57#endif
[677]58}
59
60Void TCom3DAsymLUT::destroy()
61{
62  xFree3DArray( m_pCuboid );
[852]63#if R0164_CGS_LUT_BUGFIX_CHECK
64  xFree3DArray( m_pCuboidExplicit );
65  xFree3DArray( m_pCuboidFilled   );
[825]66#endif
[677]67}
68
[877]69
[1214]70Void TCom3DAsymLUT::xUpdatePartitioning( Int nCurOctantDepth, Int nCurYPartNumLog2, Int nAdaptCThresholdU, Int nAdaptCThresholdV  )
[677]71{
72  assert( nCurOctantDepth <= m_nMaxOctantDepth );
[826]73  assert( nCurYPartNumLog2 + nCurOctantDepth <= m_nMaxYPartNumLog2 + m_nMaxOctantDepth );
[677]74
75  m_nCurOctantDepth = nCurOctantDepth;
76  m_nCurYPartNumLog2 = nCurYPartNumLog2;
77  m_nYShift2Idx = m_nInputBitDepthY - m_nCurOctantDepth - m_nCurYPartNumLog2;
78  m_nUShift2Idx = m_nVShift2Idx = m_nInputBitDepthC - m_nCurOctantDepth;
[1214]79
[825]80  m_nMappingShift = 10 + m_nInputBitDepthY - m_nOutputBitDepthY; 
81  m_nAdaptCThresholdU = nAdaptCThresholdU;
82  m_nAdaptCThresholdV = nAdaptCThresholdV;
[1214]83
[677]84  m_nMappingOffset = 1 << ( m_nMappingShift - 1 );
[877]85
86#if R0179_ENC_OPT_3DLUT_SIZE
87  m_nYSize = 1 << ( m_nCurOctantDepth + m_nCurYPartNumLog2 );
88  m_nUSize = 1 << m_nCurOctantDepth;
89  m_nVSize = 1 << m_nCurOctantDepth;
90#endif
[677]91}
92
93Void TCom3DAsymLUT::colorMapping( TComPicYuv * pcPic, TComPicYuv * pcPicDst )
94{
[1029]95  Int nWidth = pcPic->getWidth(COMPONENT_Y);
96  Int nHeight = pcPic->getHeight(COMPONENT_Y);
97  Int nStrideY = pcPic->getStride(COMPONENT_Y);
98  Int nStrideC = pcPic->getStride(COMPONENT_Cb);
99  Pel * pY = pcPic->getAddr(COMPONENT_Y);
100  Pel * pU = pcPic->getAddr(COMPONENT_Cb);
101  Pel * pV = pcPic->getAddr(COMPONENT_Cr);
[677]102
[1029]103  Int nDstStrideY = pcPicDst->getStride(COMPONENT_Y);
104  Int nDstStrideC = pcPicDst->getStride(COMPONENT_Cb);
105  Pel * pYDst = pcPicDst->getAddr(COMPONENT_Y);
106  Pel * pUDst = pcPicDst->getAddr(COMPONENT_Cb);
107  Pel * pVDst = pcPicDst->getAddr(COMPONENT_Cr);
[677]108
109  Pel *pUPrev = pU;
110  Pel *pVPrev = pV;
111  Pel *pUNext = pU+nStrideC;
112  Pel *pVNext = pV+nStrideC;
113
114  // alignment padding
[815]115  pcPic->setBorderExtension( false );
116  pcPic->extendPicBorder();
[677]117
118  Pel iMaxValY = (1<<getOutputBitDepthY())-1;
119  Pel iMaxValC = (1<<getOutputBitDepthC())-1;
120  for( Int y = 0 ; y < nHeight ; y += 2 )
121  {
122    for( Int xY = 0 , xC = 0 ; xY < nWidth ; xY += 2 , xC++ )
123    {
124      Pel srcY00 = pY[xY];
125      Pel srcY01 = pY[xY+1];
126      Pel srcY10 = pY[xY+nStrideY];
127      Pel srcY11 = pY[xY+nStrideY+1];
128      Pel srcYaver;
129      Pel srcU = pU[xC];
130      Pel srcV = pV[xC];
131      Pel dstY00, dstY01, dstY10, dstY11;
132
133      // alignment
134      srcYaver =  (srcY00 + srcY10 + 1 ) >> 1;
135      Pel srcUP0 = pUPrev[xC];
136      Pel srcVP0 = pVPrev[xC];       
137      Pel tmpU =  (srcUP0 + srcU + (srcU<<1) + 2 ) >> 2;
138      Pel tmpV =  (srcVP0 + srcV + (srcV<<1) + 2 ) >> 2;
139      dstY00 = xMapY( srcY00 , tmpU , tmpV );
140      Pel a = pU[xC+1] + srcU;
141      tmpU =  ((a<<1) + a + srcUP0 + pUPrev[xC+1] + 4 ) >> 3;
142      Pel b = pV[xC+1] + srcV;
143      tmpV =  ((b<<1) + b + srcVP0 + pVPrev[xC+1] + 4 ) >> 3;
144      dstY01 = xMapY( srcY01 , tmpU , tmpV );
145
146      srcUP0 = pUNext[xC];
147      srcVP0 = pVNext[xC];
148      tmpU =  (srcUP0 + srcU + (srcU<<1) + 2 ) >> 2;
149      tmpV =  (srcVP0 + srcV + (srcV<<1) + 2 ) >> 2;
150      dstY10 = xMapY( srcY10 , tmpU , tmpV );
151      tmpU =  ((a<<1) + a + srcUP0 + pUNext[xC+1] + 4 ) >> 3;
152      tmpV =  ((b<<1) + b + srcVP0 + pVNext[xC+1] + 4 ) >> 3;
153      dstY11 = xMapY( srcY11 , tmpU , tmpV );
154
155      SYUVP dstUV = xMapUV( srcYaver , srcU , srcV );
156      pYDst[xY] = Clip3((Pel)0, iMaxValY, dstY00 );
157      pYDst[xY+1] = Clip3((Pel)0, iMaxValY, dstY01 );
158      pYDst[xY+nDstStrideY] = Clip3((Pel)0, iMaxValY, dstY10 );
159      pYDst[xY+nDstStrideY+1] = Clip3((Pel)0, iMaxValY, dstY11 );
160      pUDst[xC] = Clip3((Pel)0, iMaxValC, dstUV.U );
161      pVDst[xC] = Clip3((Pel)0, iMaxValC, dstUV.V );
162    }
163    pY += nStrideY + nStrideY;
164
165    // alignment
166    pUPrev = pU;
167    pVPrev = pV;
168    pU = pUNext;
169    pV = pVNext;
170    pUNext += nStrideC;
171    pVNext += nStrideC;
172
173    pYDst += nDstStrideY + nDstStrideY;
174    pUDst += nDstStrideC;
175    pVDst += nDstStrideC;
176  }
177}
178
179SYUVP TCom3DAsymLUT::xGetCuboidVertexPredA( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx )
180{
181  assert( nVertexIdx < 4 );
182 
183  SYUVP sPred;
[1214]184
[825]185  sPred.Y = sPred.U = sPred.V = 0;
[1214]186
[825]187  if( nVertexIdx == 0 )
[1214]188  {
[825]189    sPred.Y = xGetNormCoeffOne() << ( m_nOutputBitDepthY - m_nInputBitDepthY );
[1214]190  }
[825]191  else if( nVertexIdx == 1 )
[1214]192  {
[825]193    sPred.U = xGetNormCoeffOne() << ( m_nOutputBitDepthY - m_nInputBitDepthY );
[1214]194  }
[825]195  else if( nVertexIdx == 2 )
[1214]196  {
[825]197    sPred.V = xGetNormCoeffOne() << ( m_nOutputBitDepthY - m_nInputBitDepthY );
[1214]198  }
199
200  return sPred;
[677]201}
202
203SYUVP  TCom3DAsymLUT::xGetCuboidVertexPredAll( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx , SCuboid *** pCurCuboid )
204{
205  SCuboid***  pCuboid = pCurCuboid ? pCurCuboid : m_pCuboid ;
206
[825]207  SYUVP sPred;
208  if( yIdx == 0 )
209  {
210    sPred.Y = nVertexIdx == 0 ? 1024 : 0;
211    sPred.U = nVertexIdx == 1 ? 1024 : 0;
212    sPred.V = nVertexIdx == 2 ? 1024 : 0;
213  }
214  else
215  {
216    sPred = pCuboid[yIdx-1][uIdx][vIdx].P[nVertexIdx];
217  }
[677]218
219  return sPred ;
220}
221
222SYUVP TCom3DAsymLUT::getCuboidVertexResTree( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx )
223{
224  const SYUVP & rYUVP = m_pCuboid[yIdx][uIdx][vIdx].P[nVertexIdx];
225  SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , nVertexIdx );
226
227  SYUVP sResidue;
228  sResidue.Y = ( rYUVP.Y - sPred.Y ) >> m_nResQuanBit;
229  sResidue.U = ( rYUVP.U - sPred.U ) >> m_nResQuanBit;
230  sResidue.V = ( rYUVP.V - sPred.V ) >> m_nResQuanBit;
231  return( sResidue );
232}
233
234Void TCom3DAsymLUT::setCuboidVertexResTree( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx , Int deltaY , Int deltaU , Int deltaV )
235{
236  SYUVP & rYUVP = m_pCuboid[yIdx][uIdx][vIdx].P[nVertexIdx];
237  SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , nVertexIdx );
238
239  rYUVP.Y = sPred.Y + ( deltaY << m_nResQuanBit );
240  rYUVP.U = sPred.U + ( deltaU << m_nResQuanBit );
241  rYUVP.V = sPred.V + ( deltaV << m_nResQuanBit );
[1213]242
[825]243  // LUT coefficients are less than 12-bit
244  assert( -2048 <= rYUVP.Y && rYUVP.Y <= 2047 );
245  assert( -2048 <= rYUVP.U && rYUVP.U <= 2047 );
246  assert( -2048 <= rYUVP.V && rYUVP.V <= 2047 );
[677]247}
248
249Pel TCom3DAsymLUT::xMapY( Pel y , Pel u , Pel v )
250{
[825]251  const SCuboid & rCuboid = m_pCuboid[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
252  Pel dstY = ( ( rCuboid.P[0].Y * y + rCuboid.P[1].Y * u + rCuboid.P[2].Y * v + m_nMappingOffset ) >> m_nMappingShift ) + rCuboid.P[3].Y;
[1214]253
[677]254  return( dstY );
255}
256
257SYUVP TCom3DAsymLUT::xMapUV( Pel y , Pel u , Pel v )
258{
[825]259  const SCuboid & rCuboid = m_pCuboid[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
260  SYUVP dst;
261  dst.Y = 0;
262  dst.U = ( ( rCuboid.P[0].U * y + rCuboid.P[1].U * u + rCuboid.P[2].U * v + m_nMappingOffset ) >> m_nMappingShift ) + rCuboid.P[3].U;
263  dst.V = ( ( rCuboid.P[0].V * y + rCuboid.P[1].V * u + rCuboid.P[2].V * v + m_nMappingOffset ) >> m_nMappingShift ) + rCuboid.P[3].V;
[1214]264
[677]265  return( dst );
266}
267
268Void TCom3DAsymLUT::xSaveCuboids( SCuboid *** pSrcCuboid )
269{
[877]270#if R0179_ENC_OPT_3DLUT_SIZE
271  memcpy( m_pCuboid[0][0] , pSrcCuboid[0][0] , sizeof( SCuboid ) * getMaxYSize() * getMaxCSize() * getMaxCSize() );
272#else
[677]273  memcpy( m_pCuboid[0][0] , pSrcCuboid[0][0] , sizeof( SCuboid ) * m_nYSize * m_nUSize * m_nVSize );
[877]274#endif
[677]275}
276
277Void TCom3DAsymLUT::copy3DAsymLUT( TCom3DAsymLUT * pSrc )
278{
279  assert( pSrc->getMaxOctantDepth() == getMaxOctantDepth() && pSrc->getMaxYPartNumLog2() == getMaxYPartNumLog2() );
[1214]280  xUpdatePartitioning( pSrc->getCurOctantDepth(), pSrc->getCurYPartNumLog2(), pSrc->getAdaptChromaThresholdU(), pSrc->getAdaptChromaThresholdV() );
[677]281  setResQuantBit( pSrc->getResQuantBit() );
282  xSaveCuboids( pSrc->m_pCuboid );
283}
284
[852]285#if R0164_CGS_LUT_BUGFIX_CHECK
[825]286Void TCom3DAsymLUT::xInitCuboids( )
287{
288  // All vertices are initialized as non-exlicitly-encoded
289  for( Int yIdx = 0 ; yIdx < m_nYSize ; yIdx++ )
290  {
291    for( Int uIdx = 0 ; uIdx < m_nUSize ; uIdx++ )
292    {
293      for( Int vIdx = 0 ; vIdx < m_nVSize ; vIdx++ )
294      { 
295        m_pCuboidExplicit[yIdx][uIdx][vIdx] = false;
[852]296        m_pCuboidFilled[yIdx][uIdx][vIdx]   = false;
[825]297      }
298    }
299  }
300}
301
[852]302Void TCom3DAsymLUT::xCuboidsFilledCheck( Int yIdx , Int uIdx , Int vIdx )
[825]303{
[852]304  if ( m_pCuboidFilled[yIdx][uIdx][vIdx] == false )
[825]305  {
306    if( yIdx > 0) 
[852]307      assert ( m_pCuboidFilled[yIdx-1][uIdx][vIdx] );
[825]308
309    for ( Int nVertexIdx=0 ; nVertexIdx<4 ; nVertexIdx++ )
310      m_pCuboid[yIdx][uIdx][vIdx].P[nVertexIdx] = yIdx == 0 ? xGetCuboidVertexPredA( yIdx , uIdx , vIdx , nVertexIdx ): xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , nVertexIdx );
311
[852]312    m_pCuboidFilled[yIdx][uIdx][vIdx] = true ;
[825]313  }
314}
315
316
[852]317Void TCom3DAsymLUT::xCuboidsFilledCheck( Bool bDecode )
[825]318{
319  Int ySize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
320  Int uSize = 1 << getCurOctantDepth();
321  Int vSize = 1 << getCurOctantDepth();
322  for( Int yIdx = 0 ; yIdx < ySize ; yIdx++ )
323  {
324    for( Int uIdx = 0 ; uIdx < uSize ; uIdx++ )
325    {
326      for( Int vIdx = 0 ; vIdx < vSize ; vIdx++ )
327      { 
328        if ( bDecode )
[852]329          xCuboidsFilledCheck( yIdx , uIdx , vIdx );
[825]330
[852]331        assert( m_pCuboidFilled[yIdx][uIdx][vIdx] );
[825]332      }
333    }
334  }
335
336}
[677]337#endif
338
[825]339Bool TCom3DAsymLUT::isRefLayer( UInt uiRefLayerId )
340{
341  Bool bIsRefLayer = false;
342  for( UInt i = 0 ; i < m_vRefLayerId.size() ; i++ )
343  {
344    if( m_vRefLayerId[i] == uiRefLayerId )
345    {
346      bIsRefLayer = true;
347      break;
348    }
349  }
350
351  return( bIsRefLayer );
352}
353
[852]354#if R0164_CGS_LUT_BUGFIX_CHECK
355Void  TCom3DAsymLUT::display( Bool bFilled )
356{
357  Int ySize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
358  Int uSize = 1 << getCurOctantDepth();
359  Int vSize = 1 << getCurOctantDepth();
360  Int vIdx=0;
361
362  printf("\n");
363  printf("3DLut Explicit flag:\n");
364  for( Int uIdx = 0 ; uIdx < uSize ; uIdx++ )
365  {
366    for( Int yIdx = 0 ; yIdx < ySize ; yIdx++ )
367    {
368      printf("%d\t", m_pCuboidExplicit[yIdx][uIdx][vIdx] );
369    }
370    printf("\n");
371  }
372
373  printf("3DLut values (explicit):\n");
374  for( Int uIdx = 0 ; uIdx < uSize ; uIdx++ )
375  {
376    for( Int yIdx = 0 ; yIdx < ySize ; yIdx++ )
377    {
378      if ( m_pCuboidExplicit[yIdx][uIdx][vIdx] )  printf("%d\t", m_pCuboid[yIdx][uIdx][vIdx].P[0].Y );
379      else                                        printf("?\t", m_pCuboid[yIdx][uIdx][vIdx].P[0].Y );
380    }
381    printf("\n");
382  }
383
384  printf("3DLut values (all):\n");
385  for( Int uIdx = 0 ; uIdx < uSize ; uIdx++ )
386  {
387    for( Int yIdx = 0 ; yIdx < ySize ; yIdx++ )
388    {
389      if ( bFilled ) {
390        if ( m_pCuboidFilled[yIdx][uIdx][vIdx] )  printf("%d\t"  , m_pCuboid[yIdx][uIdx][vIdx].P[0].Y );
391        else                                      printf("unk\t" , m_pCuboid[yIdx][uIdx][vIdx].P[0].Y );
392      }
393      else
394        printf("%d\t"  , m_pCuboid[yIdx][uIdx][vIdx].P[0].Y );
395    }
396    printf("\n");
397  }
398
399}
[825]400#endif
401
[852]402#endif
403
Note: See TracBrowser for help on using the repository browser.