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

Last change on this file since 1215 was 1214, checked in by seregin, 10 years ago

macro cleanup: R0151_CGS_3D_ASYMLUT_IMPROVE

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