source: 3DVCSoftware/trunk/source/Lib/TLibRenderer/TRenTop.cpp @ 100

Last change on this file since 100 was 100, checked in by tech, 12 years ago

Adopted modifications:

  • disparity vector generation (A0097)
  • inter-view motion prediction modification (A0049)
  • simplification of disparity vector derivation (A0126)
  • region boundary chain coding (A0070)
  • residual skip intra (A0087)
  • VSO modification (A0033/A0093)

+ Clean ups + Bug fixes

Update of cfg files (A0033 modification 2)

  • Property svn:eol-style set to native
File size: 78.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2011, ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "TRenImage.h"
35#include "TRenTop.h"
36
37#include "TRenFilter.h"
38#include <iostream>
39#include <math.h>
40#include "../TLibCommon/CommonDef.h"
41
42Void TRenTop::xGetDataPointers( PelImage*& rpcInputImage, PelImage*& rpcOutputImage, PelImage*& rpcInputDepth, PelImage*& rpcOutputDepth, PelImage*& rpcFilled, Bool bRenderDepth )
43{
44  UInt uiWidth = m_auiInputResolution[0] << m_iLog2SamplingFactor;
45
46  UInt uiSubPelWidth  = uiWidth;
47
48  if ( m_iInterpolationMode == eRenInt8Tap )
49  {
50    uiSubPelWidth <<= m_iRelShiftLUTPrec;
51  }
52
53  UInt uiHeight = m_auiInputResolution[1];
54
55  if ( m_bUVUp )
56  {
57    rpcInputDepth  = new PelImage(uiSubPelWidth, uiHeight,1,0);
58    rpcInputImage  = new PelImage(uiSubPelWidth, uiHeight,3,0);
59    rpcOutputImage = new PelImage(uiWidth,        uiHeight,3,0);
60    rpcOutputDepth = bRenderDepth  ? new PelImage(uiWidth, uiHeight,1,0) : 0;
61    rpcFilled      = new PelImage(uiWidth, uiHeight,1,0);
62  }
63  else
64  {
65    rpcInputDepth  = new PelImage(uiSubPelWidth, uiHeight,1,1);
66    rpcInputImage  = new PelImage(uiSubPelWidth, uiHeight,1,2);
67    rpcOutputImage = new PelImage(uiWidth,        uiHeight,1,2);
68    rpcOutputDepth = bRenderDepth ? new PelImage(uiWidth, uiHeight,1,1) : 0;
69    rpcFilled      = new PelImage(uiWidth,        uiHeight,1,1);
70  }
71
72}
73
74Void TRenTop::xGetDataPointerOutputImage( PelImage*& rpcOutputImage, PelImage*& rpcOutputDepth )
75{
76
77  UInt uiWidth  = m_auiInputResolution[0] << m_iLog2SamplingFactor;
78  UInt uiHeight = m_auiInputResolution[1];
79
80  if ( m_bUVUp )
81  {
82    rpcOutputImage = new PelImage(uiWidth, uiHeight,3,0);
83    rpcOutputDepth = (m_iBlendMode == eRenBlendDepthFirst ) ? new PelImage(uiWidth, uiHeight,1,0) : NULL;
84  }
85  else
86  {
87    rpcOutputImage = new PelImage(uiWidth, uiHeight,1,2);
88    rpcOutputDepth = (m_iBlendMode == eRenBlendDepthFirst ) ? new PelImage(uiWidth, uiHeight,1,1) : NULL;
89  }
90}
91
92Void TRenTop::xConvertInputVideo( PelImage* pcOrgInputImage, PelImage* pcConvInputImage)
93{
94  TRenImagePlane<Pel>*  pcOrgPlane ;
95  TRenImagePlane<Pel>*  pcConvPlane;
96
97  Int iLog2SamplingFactor = m_iLog2SamplingFactor;
98
99  if ( m_iInterpolationMode == eRenInt8Tap)
100  {
101    iLog2SamplingFactor += m_iRelShiftLUTPrec;
102  }
103
104  AOT( iLog2SamplingFactor > 2);
105
106  for (UInt uiPlane = 0; uiPlane < 3; uiPlane++)
107  {
108    pcOrgPlane  = pcOrgInputImage ->getPlane(uiPlane);
109    pcConvPlane = pcConvInputImage->getPlane(uiPlane);
110
111    if (uiPlane == 0)
112    {
113      TRenFilter::sampleHorUp    ( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
114    }
115    else
116    {
117      if ( m_bUVUp )
118      {
119        TRenFilter::sampleCUpHorUp( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
120      }
121      else
122      {
123        TRenFilter::sampleCHorUp   ( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
124      }
125    }
126  }
127}
128
129Void TRenTop::xConvertInputDepth( PelImage* pcOrgInputImage, PelImage* pcConvInputImage)
130{
131  PelImagePlane*  pcOrgPlane ;
132  PelImagePlane*  pcConvPlane;
133
134  // Full Plane
135  pcOrgPlane  = pcOrgInputImage ->getPlane(0);
136  pcConvPlane = pcConvInputImage->getPlane(0);
137
138  Int iLog2SamplingFactor = m_iLog2SamplingFactor;
139
140  if ( m_iInterpolationMode == eRenInt8Tap)
141  {
142    iLog2SamplingFactor += m_iRelShiftLUTPrec;
143  }
144  AOT( iLog2SamplingFactor > 2);
145
146  TRenFilter::sampleHorUp(iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
147
148  if ( !m_bUVUp ) //GT: depth down
149  {
150    // Quarter Plane
151    PelImagePlane* pcTempPlane = new PelImagePlane(pcOrgInputImage->getPlane(0)->getWidth(), ( pcOrgInputImage->getPlane(0)->getHeight() >> 1), REN_LUMA_MARGIN );
152
153    TRenFilter::sampleVerDown2Tap13(pcOrgInputImage->getPlane(0), pcTempPlane, PICYUV_PAD);
154    pcConvPlane = pcConvInputImage->getPlane(1);
155
156    if ( iLog2SamplingFactor == 0 )
157    {
158      TRenFilter::sampleHorDown2Tap13(pcTempPlane, pcConvPlane, 0 );
159    }
160    else
161    {
162      TRenFilter::sampleHorUp    ( iLog2SamplingFactor - 1, pcTempPlane->getPlaneData(), pcTempPlane->getStride(), pcTempPlane->getWidth(), pcTempPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
163    }
164    delete pcTempPlane;
165  }
166}
167
168Void TRenTop::xConvertInputData( PelImage* pcOrgInputImage, PelImage* pcOrgInputDepth, PelImage* pcConvInputImage, PelImage* pcConvInputDepth, Bool bMirror )
169{
170  //ToDo: remove unnecessary copying
171  if ( bMirror )
172  {
173    m_pcTempImage->assign( pcOrgInputImage );
174    TRenFilter::mirrorHor( m_pcTempImage );
175    m_pcTempImage->extendMargin();
176    xConvertInputVideo(    m_pcTempImage, pcConvInputImage );
177
178    m_pcTempImage->getPlane(0)->assign( pcOrgInputDepth->getPlane(0) );
179    TRenFilter::mirrorHor( m_pcTempImage->getPlane(0) );
180    m_pcTempImage->getPlane(0)->extendMargin();
181    xConvertInputDepth( m_pcTempImage, pcConvInputDepth );
182  }
183  else
184  {
185    m_pcTempImage->assign( pcOrgInputImage );
186    m_pcTempImage->extendMargin();
187    xConvertInputVideo( m_pcTempImage, pcConvInputImage );
188
189    m_pcTempImage->getPlane(0)->assign( pcOrgInputDepth->getPlane(0) );
190    m_pcTempImage->getPlane(0)->extendMargin();
191    xConvertInputDepth( m_pcTempImage, pcConvInputDepth );
192  }
193}
194
195
196Void TRenTop::xConvertOutputData( PelImage* pcOrgOutputImage, PelImage* pcConvOutputImage, Bool bMirror )
197{
198  Int iLog2SamplingFactor = m_iLog2SamplingFactor;
199
200  for ( UInt uiPlane = 0; uiPlane < 3; uiPlane++)
201  {
202    PelImagePlane* pcOrgPlane  = pcOrgOutputImage ->getPlane(uiPlane);
203    PelImagePlane* pcConvPlane = pcConvOutputImage->getPlane(uiPlane);
204
205    pcOrgPlane->extendMargin();
206
207    if ( uiPlane == 0 )
208    {
209      TRenFilter::sampleHorDown( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
210    }
211    else
212    {
213      if ( m_bUVUp )
214      {
215        TRenFilter::sampleCDownHorDown( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
216      }
217      else
218      {
219        TRenFilter::sampleCHorDown    ( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
220      }
221    }
222  }
223
224  if ( bMirror )
225  {
226    TRenFilter::mirrorHor( pcConvOutputImage );
227  }
228
229}
230
231Void TRenTop::setShiftLUTs( Double** ppdShiftLUTLeft, Int** ppiShiftLUTLeft, Int** ppiBaseShiftLUTLeft, Double** ppdShiftLUTRight, Int** ppiShiftLUTRight, Int** ppiBaseShiftLUTRight,  Int iRelDistToLeft )
232{
233  m_ppdShiftLUTLeft  = ppdShiftLUTLeft;
234  m_ppdShiftLUTRight = ppdShiftLUTRight;
235
236  m_ppiShiftLUTLeft  = ppiShiftLUTLeft;
237  m_ppiShiftLUTRight = ppiShiftLUTRight;
238
239  if (  m_ppdShiftLUTRight != NULL && m_ppiShiftLUTRight != NULL )
240  {
241    for( UInt uiPlane = 0; uiPlane < 2; uiPlane++)
242    {
243      for (UInt uiDepthValue = 0; uiDepthValue <= 256; uiDepthValue++)
244      {
245        m_ppdShiftLUTRightMirror[uiPlane][uiDepthValue] = - m_ppdShiftLUTRight[uiPlane][uiDepthValue];
246        m_ppiShiftLUTRightMirror[uiPlane][uiDepthValue] = - m_ppiShiftLUTRight[uiPlane][uiDepthValue];
247      }
248    }
249  }
250
251  if ( !m_bExtrapolate )
252  {
253    TRenFilter::setupZLUT( m_bBlendUseDistWeight, m_iBlendZThresPerc, iRelDistToLeft, ppiBaseShiftLUTLeft, ppiBaseShiftLUTRight, m_iBlendZThres, m_iBlendDistWeight, m_piInvZLUTLeft, m_piInvZLUTRight);
254  }
255}
256
257Void TRenTop::extrapolateView( TComPicYuv* pcPicYuvVideo, TComPicYuv* pcPicYuvDepth, TComPicYuv* pcPicYuvSynthOut, Bool bRenderFromLeft )
258{
259  AOF( m_bExtrapolate );
260  AOF( bRenderFromLeft ? m_ppiShiftLUTLeft || m_ppdShiftLUTLeft : m_ppiShiftLUTRight || m_ppdShiftLUTRight );
261  AOF( m_auiInputResolution[0] == pcPicYuvVideo->getWidth ());
262  AOF( m_auiInputResolution[1] == pcPicYuvVideo->getHeight());
263
264  PelImage cInputImage ( pcPicYuvVideo    );
265  PelImage cInputDepth ( pcPicYuvDepth    , true);
266  PelImage cOutputImage( pcPicYuvSynthOut );
267
268  m_pcOutputImage->init();
269  m_pcFilled     ->assign(REN_IS_HOLE);
270
271  xPreProcessDepth ( &cInputDepth,  &cInputDepth);
272  xConvertInputData( &cInputImage, &cInputDepth, m_pcInputImage, m_pcInputDepth, !bRenderFromLeft );
273  xShiftPixels(m_pcInputImage, m_pcInputDepth, m_pcOutputImage, m_pcFilled, bRenderFromLeft);
274  xRemBoundaryNoise ( m_pcOutputImage, m_pcFilled, m_pcOutputImage, bRenderFromLeft); // Erode
275  xFillHoles        ( m_pcOutputImage, m_pcFilled, m_pcOutputImage, bRenderFromLeft);
276  xConvertOutputData( m_pcOutputImage, &cOutputImage, !bRenderFromLeft );
277  xPostProcessImage (&cOutputImage, &cOutputImage);
278  xCutMargin        ( &cOutputImage );
279};
280
281Void TRenTop::getUsedSamplesMap( TComPicYuv* pcPicYuvDepth, TComPicYuv* pcUsedSampleMap, Bool bRenderFromLeft )
282{
283  AOF( bRenderFromLeft ? m_ppiShiftLUTLeft && m_ppdShiftLUTLeft : m_ppiShiftLUTRight && m_ppdShiftLUTRight );
284  AOF(m_auiInputResolution[0] == pcPicYuvDepth->getWidth ());
285  AOF(m_auiInputResolution[1] == pcPicYuvDepth->getHeight());
286
287  PelImage cInputDepth ( pcPicYuvDepth    , true);
288  PelImage cOutputImage( pcUsedSampleMap );
289  PelImage cInputImage ( m_auiInputResolution[0], m_auiInputResolution[1], 1, 2 );
290  cInputImage.assign(0);
291
292  m_pcFilled     ->assign(REN_IS_HOLE);
293  xConvertInputData(  &cInputImage,  &cInputDepth,   m_pcInputImage,  m_pcInputDepth, !bRenderFromLeft );
294  xShiftPixels     (m_pcInputImage, m_pcInputDepth, m_pcOutputImage, m_pcFilled, bRenderFromLeft);
295
296  xCreateAlphaMap  ( m_pcFilled, m_pcFilled, bRenderFromLeft );
297
298  if ( !bRenderFromLeft )
299  {
300    TRenFilter::mirrorHor( m_pcFilled );
301  }
302
303  TRenFilter::filledToUsedPelMap( m_pcFilled, &cOutputImage, m_iUsedPelMapMarExt );
304};
305
306
307Void TRenTop::interpolateView( TComPicYuv* pcPicYuvVideoLeft, TComPicYuv* pcPicYuvDepthLeft, TComPicYuv* pcPicYuvVideoRight, TComPicYuv* pcPicYuvDepthRight, TComPicYuv* pcPicYuvSynthOut, Int iBlendMode, Int iSimEnhBaseView )
308{
309  assert( !m_bExtrapolate );
310  assert( m_auiInputResolution[0] == pcPicYuvVideoLeft ->getWidth () );
311  assert( m_auiInputResolution[1] == pcPicYuvVideoRight->getHeight() );
312
313  AOT( iBlendMode == 3);
314  m_iBlendMode = iBlendMode;
315  m_iSimEnhBaseView = iSimEnhBaseView;
316
317  PelImage cLeftInputImage   ( pcPicYuvVideoLeft  );
318  PelImage cLeftInputDepth   ( pcPicYuvDepthLeft,  true );
319  PelImage cRightInputImage  ( pcPicYuvVideoRight );
320  PelImage cRightInputDepth  ( pcPicYuvDepthRight, true );
321  PelImage cOutputImage      ( pcPicYuvSynthOut   );
322
323  m_pcLeftOutputImage ->init();
324  m_pcRightOutputImage->init();
325  m_pcOutputImage     ->init();
326
327  if ( m_iBlendMode == eRenBlendDepthFirst )
328  {
329    m_pcOutputDepth->init();
330  }
331
332  m_pcLeftFilled ->assign(REN_IS_HOLE);
333  m_pcRightFilled->assign(REN_IS_HOLE);
334
335  xPreProcessDepth(&cLeftInputDepth , &cLeftInputDepth );
336  xPreProcessDepth(&cRightInputDepth, &cRightInputDepth);
337
338  xConvertInputData( &cLeftInputImage,  &cLeftInputDepth,  m_pcLeftInputImage,  m_pcLeftInputDepth  ,false );
339  xConvertInputData( &cRightInputImage, &cRightInputDepth, m_pcRightInputImage, m_pcRightInputDepth ,true  );
340
341  // Render from Left View to Right view
342  if ( m_iBlendMode != eRenBlendDepthFirst )
343  {
344    xShiftPixels(m_pcLeftInputImage,  m_pcLeftInputDepth, m_pcLeftOutputImage, m_pcLeftFilled, true );
345    xFillHoles  (m_pcLeftOutputImage, m_pcLeftFilled,     m_pcLeftOutputImage, true );
346  }
347
348  xShiftPixels(m_pcLeftInputDepth,  m_pcLeftInputDepth, m_pcLeftOutputDepth, m_pcLeftFilled, true );
349  xFillHoles     ( m_pcLeftOutputDepth, m_pcLeftFilled,     m_pcLeftOutputDepth, true);
350  xCreateAlphaMap( m_pcLeftFilled,      m_pcLeftFilled,     true );
351
352  // Render from Right View to Left view
353  if ( m_iBlendMode != eRenBlendDepthFirst )
354  {
355    xShiftPixels(m_pcRightInputImage , m_pcRightInputDepth, m_pcRightOutputImage, m_pcRightFilled, false );
356    xFillHoles  (m_pcRightOutputImage, m_pcRightFilled,     m_pcRightOutputImage, false);
357  }
358
359  xShiftPixels(m_pcRightInputDepth,  m_pcRightInputDepth, m_pcRightOutputDepth, m_pcRightFilled, false);
360  xFillHoles     ( m_pcRightOutputDepth, m_pcRightFilled,     m_pcRightOutputDepth, false);
361  xCreateAlphaMap( m_pcRightFilled,      m_pcRightFilled, false );
362
363  TRenFilter::mirrorHor( m_pcRightOutputImage );
364  TRenFilter::mirrorHor( m_pcRightOutputDepth );
365  TRenFilter::mirrorHor( m_pcRightFilled      );
366
367  xEnhSimilarity( m_pcLeftOutputImage, m_pcRightOutputImage, m_pcLeftFilled, m_pcRightFilled );
368
369  if ( m_iBlendMode == eRenBlendDepthFirst )
370  {
371    xBlend               ( m_pcLeftOutputDepth,  m_pcRightOutputDepth, m_pcLeftFilled,       m_pcRightFilled, m_pcLeftOutputDepth, m_pcRightOutputDepth, m_pcOutputDepth);
372
373    xBackShiftPixels     ( m_pcLeftInputImage,   m_pcOutputDepth,      m_pcLeftOutputImage,  m_pcLeftFilled  , false);
374    xFillHoles           ( m_pcLeftOutputImage,  m_pcLeftFilled,       m_pcLeftOutputImage, false);
375    xCreateAlphaMap      ( m_pcLeftFilled,       m_pcLeftFilled,       true );
376
377    TRenFilter::mirrorHor( m_pcRightInputImage );
378    xBackShiftPixels     ( m_pcRightInputImage,  m_pcOutputDepth,      m_pcRightOutputImage, m_pcRightFilled , true );
379    xFillHoles           ( m_pcRightOutputImage, m_pcRightFilled,      m_pcRightOutputImage, true);
380
381    TRenFilter::mirrorHor( m_pcRightFilled );
382    xCreateAlphaMap      ( m_pcRightFilled,      m_pcRightFilled,      true );
383    TRenFilter::mirrorHor( m_pcRightFilled );
384  }
385
386  xBlend(m_pcLeftOutputImage, m_pcRightOutputImage, m_pcLeftFilled, m_pcRightFilled, m_pcLeftOutputDepth, m_pcRightOutputDepth, m_pcOutputImage);
387  xConvertOutputData( m_pcOutputImage, &cOutputImage , false );
388
389  xPostProcessImage  ( &cOutputImage, &cOutputImage);
390  xCutMargin( &cOutputImage );
391};
392
393
394Void TRenTop::xPreProcessDepth( PelImage* pcInImage, PelImage* pcOutImage )
395{
396  if ( m_iPreProcMode == eRenPreProNone )
397    return;
398
399  PelImage* pcTemp;
400
401  if (pcInImage == pcOutImage)
402  {
403    pcTemp = pcOutImage->create();
404  }
405  else
406  {
407    pcTemp = pcOutImage;
408  }
409
410  pcTemp->assign(pcInImage);
411
412  switch ( m_iPreProcMode )
413  {
414    case eRenPreProBinom:
415      TRenFilter::binominal(pcOutImage, pcTemp, m_iPreFilterSize);
416      break;
417    case eRenPreProNone:
418      break;
419    default:
420      assert(0);
421      break;
422  }
423
424  if (pcInImage == pcOutImage)
425  {
426    pcOutImage->setData(pcTemp, true);
427    delete pcTemp;
428  };
429
430}
431
432Void TRenTop::xShiftPlanePixelsLinInt( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
433{
434  Int iWidth        = apcInputPlanes[0]->getWidth();
435  Int iHeight       = apcInputPlanes[0]->getHeight();
436
437  Int iInputStride  = apcInputPlanes [0]->getStride();
438  Int iOutputStride = apcOutputPlanes[0]->getStride();
439
440  Int iFilledStride = pcFilledPlane->getStride();
441  Int iDepthStride  = pcDepthPlane ->getStride();
442
443  pcFilledPlane->assign(REN_IS_HOLE);
444
445  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
446  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
447
448  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
449  {
450    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
451    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
452    assert( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
453    assert( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
454    assert( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
455  }
456
457  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
458  Pel* pcFilledData = pcFilledPlane->getPlaneData();
459
460  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
461  {
462    Int iPrevShiftedPos = -1;
463    Int iShiftedPos = -1;
464
465    for(Int iPosX = 0; iPosX < iWidth; iPosX ++ )
466    {
467      Bool bExtrapolate = false;
468
469      // compute disparity and shift
470      iShiftedPos  = ( iPosX << m_iRelShiftLUTPrec ) - m_aiShiftLUTCur[RemoveBitIncrement( pcDepthData[iPosX])];
471
472      if (iPosX == 0)
473      {
474        // in first iteration only get dLeftPos
475        iPrevShiftedPos = iShiftedPos;
476        continue;
477      };
478
479      Int iDeltaPos = iShiftedPos - iPrevShiftedPos;
480
481      if ( iDeltaPos <= 0 || (iDeltaPos > (2 << m_iRelShiftLUTPrec)))
482      {
483        // skip Interpolation if pixel is shifted forwards (gap) or if  pixel is shifted backwards (foreground object)
484        bExtrapolate = true;
485      };
486
487      Int iInterPolPos;
488      if (!bExtrapolate)
489      {  // Interpolate between j1 and j2
490        for (iInterPolPos = ( iPrevShiftedPos + (1 << m_iRelShiftLUTPrec) - 1 ) >> m_iRelShiftLUTPrec  ; iInterPolPos <= (iShiftedPos >> m_iRelShiftLUTPrec); iInterPolPos++)
491        {
492          if ( (iInterPolPos >= iWidth) || (iInterPolPos < (Int) 0))
493          {
494            // skip Interpolation if Interpolation position is outside frame
495            continue;
496          };
497
498          // Interpolate
499          Int iDeltaCurPos  = (iInterPolPos << m_iRelShiftLUTPrec) - iPrevShiftedPos;
500          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
501          {
502            Pel cVal  = (( apcInputData[uiCurPlane][iPosX - 1] * iDeltaPos +  ( apcInputData[uiCurPlane][iPosX] - apcInputData[uiCurPlane][iPosX - 1] ) * iDeltaCurPos ) / iDeltaPos );
503            apcOutputData[uiCurPlane][iInterPolPos]  = cVal;
504          }
505
506          pcFilledData[iInterPolPos]  = REN_IS_FILLED;
507        }
508      }
509      else
510      { // Extrapolate right from dLeftPos and left from dRightPos
511        Int iShiftedPosCeiled = (( iPrevShiftedPos + (1 << m_iRelShiftLUTPrec) - 1) >> m_iRelShiftLUTPrec ) << m_iRelShiftLUTPrec;
512        if ( (iPrevShiftedPos + (m_iRelShiftLUTPrec >> 1) ) > iShiftedPosCeiled )
513        {
514          iInterPolPos = iShiftedPosCeiled >> m_iRelShiftLUTPrec;
515
516          if ( (iInterPolPos >= iWidth) || (iInterPolPos < (Int) 0))
517          {
518            // skip Interpolation if Interpolation position is outside frame
519            iPrevShiftedPos = iShiftedPos;
520            continue;
521          };
522
523          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
524          {
525            apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX - 1];
526          }
527
528          pcFilledData[iInterPolPos]  = REN_IS_FILLED;
529        }
530
531        Int iPrevShiftedPosFloor = (iShiftedPos >> m_iRelShiftLUTPrec) << m_iRelShiftLUTPrec;
532        if (iShiftedPos - (m_iRelShiftLUTPrec > 1) < iPrevShiftedPosFloor )
533        {
534          iInterPolPos = iPrevShiftedPosFloor >> m_iRelShiftLUTPrec;
535
536          if ( (iInterPolPos >= iWidth) || (iInterPolPos < (Int) 0))
537          {
538            // skip Interpolation if Interpolation position is outside frame
539            iPrevShiftedPos = iShiftedPos;
540            continue;
541          };
542
543          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
544          {
545            apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX ];
546          }
547
548          pcFilledData[iInterPolPos]  = REN_IS_FILLED;
549        }
550      }
551      iPrevShiftedPos = iShiftedPos;
552    }
553
554    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
555    {
556      apcOutputData[uiCurPlane] += iOutputStride;
557      apcInputData [uiCurPlane] += iInputStride;
558    }
559    pcFilledData += iFilledStride;
560    pcDepthData  += iDepthStride;
561  }
562  delete[] apcInputData;
563  delete[] apcOutputData;
564};
565
566
567Void TRenTop::xShiftPlanePixelsLinReal( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
568{
569  Int iWidth        = apcInputPlanes[0]->getWidth();
570  Int iHeight       = apcInputPlanes[0]->getHeight();
571
572  Int iInputStride  = apcInputPlanes [0]->getStride();
573  Int iOutputStride = apcOutputPlanes[0]->getStride();
574
575  Int iFilledStride = pcFilledPlane->getStride();
576  Int iDepthStride  = pcDepthPlane ->getStride();
577
578  pcFilledPlane->assign( REN_IS_HOLE );
579
580  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
581  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
582
583  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
584  {
585    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
586    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
587    assert( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
588    assert( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
589    assert( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
590  }
591
592  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
593  Pel* pcFilledData = pcFilledPlane->getPlaneData();
594
595  ///// FEM Stuff /////
596  const UInt  cuiMaxPlaneNum = 6;  AOT( uiNumberOfPlanes > cuiMaxPlaneNum );
597  IntImagePlane* apcDiffPlane[ cuiMaxPlaneNum ];
598  Int*          ppiDiffPlanes[ cuiMaxPlaneNum ];
599  Int             iDiffStride = 0;
600
601  if ( m_iInterpolationMode == eRenIntFEM )
602  {
603    AOT( uiNumberOfPlanes > cuiMaxPlaneNum );
604    for ( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
605    {
606      apcDiffPlane[uiCurPlane] = new IntImagePlane( iWidth, iHeight, apcInputPlanes[uiCurPlane]->getPad());
607      TRenFilter::diffHorSym(apcInputPlanes[uiCurPlane] , apcDiffPlane[uiCurPlane]);
608      ppiDiffPlanes[uiCurPlane] = apcDiffPlane[uiCurPlane]->getPlaneData();
609    }
610    iDiffStride = apcDiffPlane[0]->getStride();
611  }
612  ///// FEM Stuff End /////
613
614  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
615  {
616    Double dShiftedPos = 0;
617    Double dPrevShiftedPos = 0;
618
619    for(Int iPosX = 0; iPosX < iWidth; iPosX ++ )
620    {
621        Bool bExtrapolate = false;
622
623        // compute disparity and shift
624        assert( RemoveBitIncrement(pcDepthData[iPosX]) >= 0 && RemoveBitIncrement(pcDepthData[iPosX]) <= 256 );
625        dPrevShiftedPos  = (Double) iPosX - m_adShiftLUTCur[ RemoveBitIncrement(pcDepthData[iPosX])];
626
627        if (iPosX == 0)
628        {
629          // in first iteration only get dLeftPos
630          dShiftedPos = dPrevShiftedPos;
631          continue;
632        };
633
634        Double dDeltaPos = dPrevShiftedPos - dShiftedPos;
635
636        if ((dDeltaPos <= 0) || ( dDeltaPos > 2 ))
637        {
638          // skip Interpolation if pixel is shifted backwards (foreground object)  or if pixel is shifted forwards (gap)
639          bExtrapolate = true;
640        };
641
642        Int iInterPolPos;
643        if (!bExtrapolate)
644        {  // Interpolate between j1 and j2
645          for (iInterPolPos = (Int) ceil(dShiftedPos); iInterPolPos <= floor(dPrevShiftedPos); iInterPolPos++)
646          {
647            if ( (iInterPolPos >= (Int) iWidth) || (iInterPolPos < (Int) 0 ))
648            {
649              // skip Interpolation if Interpolation position is outside frame
650              continue;
651            };
652
653            // Interpolate
654            Pel cVal;
655            if ( m_iInterpolationMode == eRenIntFEM ) //FEM Interpolation
656            {
657              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
658              {
659                cVal  = TRenFilter::interpCHSpline(iInterPolPos, dShiftedPos, dPrevShiftedPos, apcInputData[uiCurPlane][iPosX - 1], ppiDiffPlanes[uiCurPlane][iPosX - 1], apcInputData[uiCurPlane][iPosX], ppiDiffPlanes[uiCurPlane][iPosX] );
660                apcOutputData[uiCurPlane][iInterPolPos]  = cVal;
661              }
662            }
663            else
664            {
665              Double dDeltaJ  = (Double) iInterPolPos - dShiftedPos;
666
667              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
668              {
669                cVal  = (UChar) ( (Double) apcInputData[uiCurPlane][iPosX - 1] +  ( (Double) apcInputData[uiCurPlane][iPosX] - (Double) apcInputData[uiCurPlane][iPosX - 1] ) / dDeltaPos * dDeltaJ + 0.5);
670                apcOutputData[uiCurPlane][iInterPolPos]  = cVal;
671              }
672            };
673
674            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
675          }
676        }
677        else
678        { // Extrapolate right from dLeftPos and left from dRightPos
679          if (dShiftedPos + 0.5 > ceil(dShiftedPos))
680          {
681            iInterPolPos = (Int) ceil(dShiftedPos);
682
683            if ( (iInterPolPos >= (Int) iWidth) || (iInterPolPos < (Int) 0))
684            {
685              // skip Interpolation if Interpolation position is outside frame
686              dShiftedPos = dPrevShiftedPos;
687              continue;
688            };
689
690            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
691            {
692              apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX - 1];
693            }
694
695            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
696          }
697
698          if (dPrevShiftedPos - 0.5 < floor(dPrevShiftedPos))
699          {
700            iInterPolPos = (Int) floor(dPrevShiftedPos);
701
702            if ( (iInterPolPos >= (Int) iWidth) || (iInterPolPos < (Int) 0))
703            {
704              // skip Interpolation if Interpolation position is outside frame
705              dShiftedPos = dPrevShiftedPos;
706              continue;
707            };
708
709            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
710            {
711              apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX ];
712            }
713
714            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
715          }
716        }
717        dShiftedPos = dPrevShiftedPos;
718      }
719
720    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
721    {
722      apcOutputData[uiCurPlane] += iOutputStride;
723      apcInputData [uiCurPlane] += iInputStride;
724
725      if (m_iInterpolationMode ==  eRenIntFEM)
726      {
727        ppiDiffPlanes[ uiCurPlane ] += iDiffStride;
728      }
729    }
730
731    pcFilledData += iFilledStride;
732    pcDepthData  += iDepthStride;
733  }
734
735  if (m_iInterpolationMode ==  eRenIntFEM)
736  {
737    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
738    {
739      delete apcDiffPlane[uiCurPlane];
740    }
741  }
742
743  delete[] apcInputData;
744  delete[] apcOutputData;
745}
746
747
748Void TRenTop::xShiftPlanePixels( PelImagePlane** apcInPlane, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutPlane, PelImagePlane* pcPlaneFilled, UInt uiNumberOfPlanes )
749{
750  switch ( m_iInterpolationMode)
751  {
752  case eRenIntFullPel:
753    xShiftPlanePixelsFullPel( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes);
754    break;
755  case eRenIntFEM:
756  case eRenIntLinReal:
757    xShiftPlanePixelsLinReal( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes);
758    break;
759  case eRenIntLinInt:
760    xShiftPlanePixelsLinInt ( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes);
761    break;
762  case eRenInt8Tap:
763    xShiftPlanePixels8Tap   ( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes );
764    break;
765  default:
766    AOF( false );
767  }
768}
769
770
771Void TRenTop::xShiftPlanePixelsFullPel( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
772{
773  Int iWidth        = apcInputPlanes[0]->getWidth();
774  Int iHeight       = apcInputPlanes[0]->getHeight();
775
776  Int iInputStride  = apcInputPlanes [0]->getStride();
777  Int iOutputStride = apcOutputPlanes[0]->getStride();
778
779  Int iFilledStride = pcFilledPlane->getStride();
780  Int iDepthStride  = pcDepthPlane ->getStride();
781
782  pcFilledPlane->assign(REN_IS_HOLE);
783
784  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
785  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
786
787  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
788  {
789    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
790    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
791    assert( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
792    assert( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
793    assert( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
794  }
795
796  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
797  Pel* pcFilledData = pcFilledPlane->getPlaneData();
798
799  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
800  {
801    Int iPrevShiftedPos = -1;
802
803    for(Int iPosX = 0; iPosX < iWidth; iPosX++)
804    {
805      assert( RemoveBitIncrement(pcDepthData[iPosX]) >= 0 && RemoveBitIncrement(pcDepthData[iPosX]) <= 256 );
806      Int iShiftedPos = iPosX - m_aiShiftLUTCur[ RemoveBitIncrement(pcDepthData[iPosX])] ;
807      if (iShiftedPos < iWidth && iShiftedPos >= 0)
808      {
809        Int iDiff = iShiftedPos - iPrevShiftedPos;
810        if (( iDiff <= 2) && (iDiff > 0) )
811        {
812          for (Int iCurPos = iPrevShiftedPos+1; iCurPos <= iShiftedPos; iCurPos++)
813          {
814            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
815            {
816              apcOutputData[uiCurPlane][iCurPos] = apcInputData[uiCurPlane][iPosX];    // Only small gaps, therefor not necessary NN
817            }
818            pcFilledData[iCurPos] = REN_IS_FILLED;
819          }
820        }
821        else
822        {
823          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
824          {
825            apcOutputData[uiCurPlane][iShiftedPos] = apcInputData[uiCurPlane][iPosX];
826          }
827          pcFilledData[iShiftedPos] = REN_IS_FILLED;
828        }
829        iPrevShiftedPos = iShiftedPos;
830      }
831    }
832    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
833    {
834      apcOutputData[uiCurPlane] += iOutputStride;
835      apcInputData [uiCurPlane] += iInputStride;
836    }
837    pcFilledData += iFilledStride;
838    pcDepthData  += iDepthStride;
839  }
840
841  delete[] apcInputData;
842  delete[] apcOutputData;
843}
844
845Void TRenTop::xBackShiftPlanePixels( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
846{
847  Int iOutputWidth  = apcOutputPlanes[0]->getWidth();
848  Int iInputWidth   = apcInputPlanes [0]->getWidth();
849  Int iHeight       = apcInputPlanes [0]->getHeight();
850
851  Int iInputStride  = apcInputPlanes [0]->getStride();
852  Int iOutputStride = apcOutputPlanes[0]->getStride();
853
854  Int iFilledStride = pcFilledPlane->getStride();
855  Int iDepthStride  = pcDepthPlane ->getStride();
856
857  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
858  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
859
860  Int iStep         = (1 << m_iRelShiftLUTPrec);
861
862  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
863  {
864    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
865    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
866    AOF( iInputWidth   == apcInputPlanes [uiCurPlane]->getWidth()  && iOutputWidth  == apcOutputPlanes[uiCurPlane]->getWidth() );
867    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
868    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
869    AOF( iInputWidth   == iOutputWidth * iStep );
870  }
871
872  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
873  Pel* pcFilledData = pcFilledPlane->getPlaneData();
874
875
876  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
877  {
878    for(Int iPosX = 0; iPosX < iOutputWidth; iPosX ++)
879    {
880      Int iBackShiftedPos = (iPosX << m_iRelShiftLUTPrec) - m_aiShiftLUTCur[ RemoveBitIncrement( pcDepthData[iPosX] )];
881      if( ( pcFilledData[iPosX] == REN_IS_FILLED )  && (iBackShiftedPos >= 0 ) && ( iBackShiftedPos < iInputWidth ) )
882      {
883        for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
884        {
885          apcOutputData[uiCurPlane][iPosX] = apcInputData[uiCurPlane][iBackShiftedPos];
886        }
887      }
888      else
889      {
890        for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
891        {
892          apcOutputData[uiCurPlane][iPosX] = 0;
893        }
894        pcFilledData[iPosX] = REN_IS_HOLE;
895      }
896    }
897
898    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
899    {
900      apcOutputData[uiCurPlane] += iOutputStride;
901      apcInputData [uiCurPlane] += iInputStride;
902    }
903    pcFilledData += iFilledStride;
904    pcDepthData  += iDepthStride;
905  }
906
907  delete[] apcInputData;
908  delete[] apcOutputData;
909}
910
911Void TRenTop::xShiftPlanePixels8Tap( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes  )
912{
913  Bool bRenderDepth = (apcInputPlanes[0] == pcDepthPlane);
914
915  Int iOutputWidth  = apcOutputPlanes[0]->getWidth();
916  Int iInputWidth   = apcInputPlanes [0]->getWidth();
917  Int iHeight       = apcInputPlanes [0]->getHeight();
918
919  Int iInputStride  = apcInputPlanes [0]->getStride();
920  Int iOutputStride = apcOutputPlanes[0]->getStride();
921
922  Int iFilledStride = pcFilledPlane->getStride();
923  Int iDepthStride  = pcDepthPlane ->getStride();
924
925  Int iStep         = (1 << m_iRelShiftLUTPrec);
926
927  pcFilledPlane->assign(REN_IS_HOLE);
928
929  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
930  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
931
932  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
933  {
934    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
935    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
936    AOF( iInputWidth   == apcInputPlanes [uiCurPlane]->getWidth()  && iOutputWidth  == apcOutputPlanes[uiCurPlane]->getWidth() );
937    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
938    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
939    AOF( iInputWidth   == iOutputWidth * iStep );
940  }
941
942  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
943  Pel* pcFilledData = pcFilledPlane->getPlaneData();
944
945  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
946  {
947    Int iPrevShiftedPos = -1;
948    Int iShiftedPos     = -1;
949
950    for(Int iPosX = 0; iPosX < iInputWidth; iPosX += iStep )
951    {
952      // compute disparity and shift
953      iShiftedPos  =  iPosX - m_aiShiftLUTCur[RemoveBitIncrement(pcDepthData[iPosX])];
954
955      if ( iPosX == 0 )
956      {
957        // in first iteration only get dLeftPos
958        iPrevShiftedPos = iShiftedPos;
959        continue;
960      };
961
962      Int iDeltaPos = iShiftedPos - iPrevShiftedPos;
963
964      Bool bDisocclusion = ( iDeltaPos > (2 << m_iRelShiftLUTPrec) );
965      Bool bOcclusion    = ( iDeltaPos <= 0 );
966
967      Int iInterPolPos;
968      if ( !bDisocclusion && !bOcclusion )
969      {  // Interpolate between previous shifted pos and shifted pos
970        for (iInterPolPos = xCeil( iPrevShiftedPos ); iInterPolPos <= xCeil (iShiftedPos ) -1 ; iInterPolPos++)
971        {
972          if ( (iInterPolPos < (Int) 0) || (iInterPolPos >= iOutputWidth))
973          {
974            // skip Interpolation if Interpolation position is outside frame
975            continue;
976          };
977
978          // Interpolate
979          Int iDeltaCurPos  = (iInterPolPos << m_iRelShiftLUTPrec) - iPrevShiftedPos;
980
981          AOF( (iDeltaCurPos <= iDeltaPos) && ( iDeltaCurPos >= 0));
982          AOF( iDeltaPos    <= (2 <<  m_iRelShiftLUTPrec)  );
983          AOF( m_aaiSubPelShift[iDeltaPos][iDeltaCurPos] != 0xdeaddead);
984
985          Int iSourcePos;
986
987          if ( bRenderDepth )
988          {
989            iSourcePos = iPosX - iStep; // Render depth with Full Pel accuracy to avoid ringing at sharp depth edges;
990          }
991          else
992          {
993            iSourcePos = iPosX +  m_aaiSubPelShift[iDeltaPos][iDeltaCurPos];   // GT:  = iPosX - iStep + ( iStep * iDeltaCurPos + ( iDeltaPos >> 1) ) / iDeltaPos;
994          }
995
996          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
997          {
998            apcOutputData[uiCurPlane][iInterPolPos] = apcInputData[uiCurPlane][iSourcePos];
999          }
1000
1001          pcFilledData[ iInterPolPos]  = REN_IS_FILLED;
1002        }
1003      }
1004      else
1005        {
1006        // Fill Disocclusion Edge
1007
1008        if ( bDisocclusion )
1009        {
1010          Int iPrevShiftedPosCeiled =  xCeil(iPrevShiftedPos) << m_iRelShiftLUTPrec;
1011          iInterPolPos = iPrevShiftedPosCeiled >> m_iRelShiftLUTPrec;
1012
1013          if ((iPrevShiftedPos + (iStep >> 1) ) > iPrevShiftedPosCeiled )
1014          {
1015            if ( !((iInterPolPos < (Int) 0) || (iInterPolPos >= iOutputWidth)))
1016            {
1017
1018              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1019              {
1020                apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX - iStep];
1021              }
1022              pcFilledData[iInterPolPos]  = REN_IS_FILLED;
1023
1024            }           
1025            iInterPolPos++;
1026          }         
1027
1028          // Fill Disocclusion
1029          if ( m_bInstantHoleFilling )
1030          {
1031            for ( ; iInterPolPos <= xCeil (iShiftedPos ) -1 ; iInterPolPos++)
1032            {
1033              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1034              {
1035                if ( ( iInterPolPos >= 0 ) && ( iInterPolPos < iOutputWidth ) )
1036                {
1037                  apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX];
1038                }
1039              }
1040            }
1041          }
1042        }
1043
1044        //// Last sample next to occlusion
1045        Int iShiftedPosFloor = ( iShiftedPos >> m_iRelShiftLUTPrec ) << m_iRelShiftLUTPrec;
1046        if ( bOcclusion && (iShiftedPos - (iStep >> 1) < iShiftedPosFloor) )
1047        {
1048          iInterPolPos = iShiftedPosFloor >> m_iRelShiftLUTPrec;
1049          if ( !((iInterPolPos < (Int) 0) || (iInterPolPos >= iOutputWidth)))
1050          {       
1051            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1052            {
1053              apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX ];
1054            }
1055
1056            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
1057          }
1058        }
1059      }
1060      iPrevShiftedPos = iShiftedPos;
1061    }
1062
1063    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1064    {
1065      apcOutputData[uiCurPlane] += iOutputStride;
1066      apcInputData [uiCurPlane] += iInputStride;
1067    }
1068    pcFilledData += iFilledStride;
1069    pcDepthData  += iDepthStride;
1070  }
1071  delete[] apcInputData;
1072  delete[] apcOutputData;
1073};
1074
1075Void TRenTop::xShiftPixels(PelImage* pcInImage, PelImage* pcDepth, PelImage* pcOutImage, PelImage* pcFilledImage, Bool bShiftFromLeft )
1076{
1077  PelImage*  pcTemp = 0;
1078
1079  if (pcInImage == pcOutImage)
1080  {
1081    pcTemp = pcOutImage->create();
1082  }
1083  else
1084  {
1085    pcTemp = pcOutImage;
1086  }
1087
1088  Double ** ppdShiftLUT = bShiftFromLeft ? m_ppdShiftLUTLeft : m_ppdShiftLUTRightMirror;
1089  Int    ** ppiShiftLUT = bShiftFromLeft ? m_ppiShiftLUTLeft : m_ppiShiftLUTRightMirror;
1090
1091  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1092  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1093
1094  assert( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1095  assert( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1096
1097  m_aiShiftLUTCur = ppiShiftLUT[ 0 ];
1098  m_adShiftLUTCur = ppdShiftLUT[ 0 ];
1099
1100  xShiftPlanePixels( pcInImage->getPlanes(), pcDepth->getPlane(0),  pcOutImage->getPlanes(), pcFilledImage->getPlane(0),  uiNumFullPlanes  );
1101
1102  if (uiNumQuatPlanes > 0)
1103  {
1104    assert( pcDepth->getNumberOfPlanes() > 1 && pcFilledImage->getNumberOfPlanes() > 1);
1105    m_aiShiftLUTCur = ppiShiftLUT[ 1 ];
1106    m_adShiftLUTCur = ppdShiftLUT[ 1 ];
1107    xShiftPlanePixels( pcInImage->getPlanes()+uiNumFullPlanes,pcDepth->getPlane(1),  pcOutImage->getPlanes() + uiNumFullPlanes, pcFilledImage->getPlane(1),  uiNumQuatPlanes );
1108  }
1109
1110  if (pcInImage == pcOutImage)
1111  {
1112    pcOutImage->assign(pcTemp);
1113    delete pcTemp;
1114  };
1115};
1116
1117Void TRenTop::xBackShiftPixels(PelImage* pcInImage, PelImage* pcDepth, PelImage* pcOutImage, PelImage* pcFilledImage, Bool bShiftFromLeft )
1118{
1119  PelImage*  pcTemp = 0;
1120
1121  if (pcInImage == pcOutImage)
1122  {
1123    pcTemp = pcOutImage->create();
1124  }
1125  else
1126  {
1127    pcTemp = pcOutImage;
1128  }
1129
1130  Double ** ppdShiftLUT = bShiftFromLeft ? m_ppdShiftLUTLeft : m_ppdShiftLUTRight;
1131  Int    ** ppiShiftLUT = bShiftFromLeft ? m_ppiShiftLUTLeft : m_ppiShiftLUTRight;
1132
1133  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1134  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1135
1136  assert( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1137  assert( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1138
1139  m_aiShiftLUTCur = ppiShiftLUT[ 0 ];
1140  m_adShiftLUTCur = ppdShiftLUT[ 0 ];
1141
1142  xBackShiftPlanePixels( pcInImage->getPlanes(), pcDepth->getPlane(0),  pcOutImage->getPlanes(), pcFilledImage->getPlane(0),  uiNumFullPlanes  );
1143
1144  if (uiNumQuatPlanes > 0)
1145  {
1146    assert( pcDepth->getNumberOfPlanes() > 1 && pcFilledImage->getNumberOfPlanes() > 1);
1147    m_aiShiftLUTCur = ppiShiftLUT[ 1 ];
1148    m_adShiftLUTCur = ppdShiftLUT[ 1 ];
1149    xBackShiftPlanePixels( pcInImage->getPlanes()+uiNumFullPlanes,pcDepth->getPlane(1),  pcOutImage->getPlanes() + uiNumFullPlanes, pcFilledImage->getPlane(1),  uiNumQuatPlanes );
1150  }
1151
1152  if (pcInImage == pcOutImage)
1153  {
1154    pcOutImage->assign(pcTemp);
1155    delete pcTemp;
1156  };
1157};
1158
1159Void TRenTop::xFillHoles(PelImage* pcInImage, PelImage* pcFilled, PelImage* pcOutImage, Bool bRenderFromLeft )
1160{
1161  if (pcInImage != pcOutImage)
1162  {
1163    pcOutImage->assign(pcInImage);
1164  }
1165
1166  switch (m_iHoleFillingMode)
1167  {
1168    case eRenHFNone:
1169      break;
1170    case eRenHFLWBackExt:
1171      xFillLWBackExt( pcInImage, pcFilled, pcOutImage, bRenderFromLeft);
1172      break;
1173    default:
1174      break;
1175  }
1176};
1177
1178Void TRenTop::xFillLWBackExt( PelImage* pcInImage, PelImage* pcFilledImage, PelImage* pcOutImage, Bool bRenderFromLeft )
1179{
1180  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1181  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1182
1183  assert( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1184  assert( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1185
1186  xFillPlaneHoles( pcInImage->getPlanes(), pcFilledImage->getPlane(0), pcOutImage->getPlanes(),  uiNumFullPlanes, bRenderFromLeft  );
1187
1188  if (uiNumQuatPlanes > 0)
1189  {
1190    assert(  pcFilledImage->getNumberOfPlanes() > 1);
1191    xFillPlaneHoles( pcInImage->getPlanes()+uiNumFullPlanes, pcFilledImage->getPlane(1), pcOutImage->getPlanes() + uiNumFullPlanes,  uiNumQuatPlanes, bRenderFromLeft );
1192  }
1193};
1194
1195Void TRenTop::xCreateAlphaMap(PelImage* pcFilledImage, PelImage* pcAlphaMapImage, Bool bRenderFromLeft )
1196{
1197  UInt uiNumFullPlanes = pcFilledImage  ->getNumberOfFullPlanes();
1198  UInt uiNumQuatPlanes = pcFilledImage->getNumberOfQuaterPlanes();
1199
1200  AOF( uiNumFullPlanes == pcAlphaMapImage->getNumberOfFullPlanes  () );
1201  AOF( uiNumQuatPlanes == pcAlphaMapImage->getNumberOfQuaterPlanes() );
1202
1203  xCreateAlphaMapPlane( pcFilledImage->getPlanes(),  pcAlphaMapImage->getPlanes(),  uiNumFullPlanes, bRenderFromLeft  );
1204
1205  if (uiNumQuatPlanes > 0)
1206  {
1207    AOF(  pcFilledImage->getNumberOfPlanes() > 1);
1208    xCreateAlphaMapPlane( pcFilledImage->getPlanes()+ uiNumFullPlanes, pcAlphaMapImage->getPlanes()+uiNumFullPlanes,  uiNumQuatPlanes, bRenderFromLeft );
1209  }
1210};
1211
1212Void TRenTop::xCreateAlphaMapPlane(PelImagePlane** apcFilledPlanes,  PelImagePlane** apcAlphaPlanes,  UInt uiNumberOfPlanes, Bool bRenderFromLeft)
1213{
1214  Int iWidth            = apcFilledPlanes [0]->getWidth();
1215  Int iHeight           = apcFilledPlanes [0]->getHeight();
1216
1217  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1218  {
1219    AOF( iWidth         == apcFilledPlanes [uiCurPlane]->getWidth()  && iWidth        == apcAlphaPlanes[uiCurPlane]->getWidth() );
1220    AOF( iHeight        == apcFilledPlanes [uiCurPlane]->getHeight() && iHeight       == apcAlphaPlanes[uiCurPlane]->getHeight());
1221  }
1222
1223  Int iBlendWidth  = m_iBlendHoleMargin;
1224  Int iMaxBlendLevel;
1225
1226  if (!m_bBlendUseDistWeight )
1227  {
1228    iMaxBlendLevel = ( 1 <<  REN_VDWEIGHT_PREC ) ;
1229
1230    if ( m_iBlendMode == 0)
1231    {
1232      iMaxBlendLevel >>= 1;
1233    }
1234  }
1235  else
1236  {
1237    if ( m_iBlendMode == 0)
1238    {
1239      iMaxBlendLevel = bRenderFromLeft ? (1 << REN_VDWEIGHT_PREC) - m_iBlendDistWeight :  m_iBlendDistWeight;
1240    }
1241    else
1242    {
1243      iMaxBlendLevel  = ( 1 <<  REN_VDWEIGHT_PREC );
1244    }
1245  }
1246
1247  Int iWeightStep = (iBlendWidth > 0) ? ( iMaxBlendLevel + (iBlendWidth >> 1) ) / iBlendWidth : 0;
1248
1249  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1250  {
1251    Int iFilledStride   = apcFilledPlanes [uiCurPlane]->getStride();
1252    Int iAlphaStride    = apcAlphaPlanes  [uiCurPlane]->getStride();
1253
1254    Pel* pcFilledData = apcFilledPlanes   [uiCurPlane]->getPlaneData();
1255    Pel* pcAlphaData  = apcAlphaPlanes    [uiCurPlane]->getPlaneData();
1256
1257    for(Int iYPos = 0; iYPos < iHeight; iYPos++)
1258    {
1259      for(Int iXPos = 0 ; iXPos < iWidth; iXPos++ )
1260      {
1261        if (pcFilledData[iXPos] == REN_IS_HOLE)
1262        {
1263          while( (pcFilledData[iXPos] == REN_IS_HOLE) && (iXPos < iWidth) )
1264          {
1265            pcAlphaData[iXPos] = REN_IS_HOLE;
1266            iXPos++;
1267          }
1268
1269          if ( iXPos >= iWidth )
1270            continue;
1271
1272          Int iWeight = 0;
1273          Int iLastFillPos = iXPos + iBlendWidth;
1274
1275          while( (pcFilledData[iXPos] != REN_IS_HOLE) && (iXPos < iWidth) && (iXPos < iLastFillPos) )
1276          {
1277            AOF(  iWeight <= (1 << REN_VDWEIGHT_PREC) );
1278            pcAlphaData[iXPos]  = (iWeight == 0) ? 1 : iWeight;
1279            iWeight += iWeightStep;
1280            iXPos++;
1281          }
1282        }
1283        else
1284        {
1285          pcAlphaData[iXPos] = REN_IS_FILLED;
1286        }
1287      }
1288      pcAlphaData    += iAlphaStride;
1289      pcFilledData   += iFilledStride;
1290    }
1291  }
1292}
1293
1294Void TRenTop::xRemBoundaryNoise(PelImage* pcInImage, PelImage* pcFilledImage, PelImage* pcOutImage, Bool bRenderFromLeft )
1295{
1296  if (pcInImage != pcOutImage)
1297  {
1298    pcOutImage->assign(pcInImage);
1299  }
1300
1301  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1302  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1303
1304  AOF( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1305  AOF( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1306
1307  xRemBoundaryNoisePlane( pcInImage->getPlanes(), pcFilledImage->getPlane(0), pcOutImage->getPlanes(),  uiNumFullPlanes, bRenderFromLeft  );
1308
1309  if (uiNumQuatPlanes > 0)
1310  {
1311    AOF(  pcFilledImage->getNumberOfPlanes() > 1);
1312    xRemBoundaryNoisePlane( pcInImage->getPlanes()+uiNumFullPlanes, pcFilledImage->getPlane(1), pcOutImage->getPlanes() + uiNumFullPlanes,  uiNumQuatPlanes, bRenderFromLeft );
1313  }
1314};
1315
1316Void TRenTop::xRemBoundaryNoisePlane(PelImagePlane** apcInputPlanes,  PelImagePlane* pcFilledPlane, PelImagePlane** apcOutputPlanes, UInt uiNumberOfPlanes, Bool bRenderFromLeft)
1317{
1318  Int iWidth        = apcOutputPlanes[0]->getWidth();
1319  Int iHeight       = apcInputPlanes [0]->getHeight();
1320
1321  Int iInputStride  = apcInputPlanes [0]->getStride();
1322  Int iOutputStride = apcOutputPlanes[0]->getStride();
1323
1324  Int iFilledStride = pcFilledPlane->getStride();
1325
1326  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
1327  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
1328  Pel*   pcFilledData = pcFilledPlane->getPlaneData();
1329
1330  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1331  {
1332    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
1333    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
1334    AOF( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
1335    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
1336    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
1337  }
1338
1339  Int iRemovalWidth  = m_iBlendHoleMargin;
1340  AOT(iRemovalWidth > 6);  // GT: insufficent padding
1341
1342  for(Int iYPos = 0; iYPos < iHeight; iYPos++)
1343  {
1344    for(Int iXPos = iWidth-1; iXPos >= 0; iXPos-- )
1345    {
1346      if (pcFilledData[iXPos] == REN_IS_HOLE)
1347      {
1348        Int iSourcePos = iXPos + 1;
1349
1350        // Get New Value
1351        while( (pcFilledData[iSourcePos] != REN_IS_HOLE) && ( iSourcePos < iWidth) && ( iSourcePos < iXPos + iRemovalWidth  ) ) iSourcePos++;
1352
1353        if (iSourcePos == iWidth || pcFilledData[iSourcePos] != REN_IS_HOLE )
1354          iSourcePos--;
1355
1356        Int iXPosRem = iSourcePos - 1;
1357
1358        // Remove
1359        while( iXPosRem > iXPos)
1360        {
1361          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1362          {
1363            apcOutputData[uiCurPlane][iXPosRem] = apcInputData[uiCurPlane][iSourcePos];
1364          }
1365
1366          iXPosRem--;
1367        }
1368
1369        // Skip Hole
1370        while( (pcFilledData[iXPos] == REN_IS_HOLE) && ( iXPos > 0) ) iXPos--;
1371      }
1372    }
1373
1374    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1375    {
1376      apcOutputData[uiCurPlane] += iOutputStride;
1377      apcInputData [uiCurPlane] += iInputStride;
1378    }
1379    pcFilledData += iFilledStride;
1380  }
1381  delete[] apcInputData;
1382  delete[] apcOutputData;
1383}
1384
1385Void TRenTop::xFillPlaneHoles(PelImagePlane** apcInputPlanes,  PelImagePlane* pcFilledPlane, PelImagePlane** apcOutputPlanes, UInt uiNumberOfPlanes, Bool bRenderFromLeft)
1386{
1387  Int iWidth        = apcOutputPlanes[0]->getWidth();
1388  Int iHeight       = apcInputPlanes [0]->getHeight();
1389
1390  Int iInputStride  = apcInputPlanes [0]->getStride();
1391  Int iOutputStride = apcOutputPlanes[0]->getStride();
1392
1393  Int iFilledStride = pcFilledPlane->getStride();
1394
1395  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
1396  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
1397  Pel*   pcFilledData = pcFilledPlane->getPlaneData();
1398
1399  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1400  {
1401    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
1402    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
1403    AOF( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
1404    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
1405    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
1406  }
1407
1408  for(Int iYPos = 0; iYPos < iHeight; iYPos++)
1409  {
1410    if ( !m_bInstantHoleFilling )
1411    {
1412    for(Int iXPos = 0 ; iXPos < iWidth; iXPos++ )
1413    {
1414      if (pcFilledData[iXPos] == REN_IS_HOLE)
1415      {
1416          Int iSourcePos;
1417          Int iLastFillPos;
1418
1419        Int iXPosSearch = iXPos;
1420        while( (pcFilledData[iXPosSearch] == REN_IS_HOLE) && (iXPosSearch < iWidth) ) iXPosSearch++;
1421
1422          if ( iXPosSearch >= iWidth )
1423        {
1424            continue;
1425          }
1426          else
1427          {
1428            iSourcePos   = iXPosSearch;
1429            iLastFillPos = iXPosSearch-1;
1430          }
1431
1432        while( iXPos <= iLastFillPos)
1433        {
1434          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1435          {
1436            apcOutputData[uiCurPlane][iXPos] = apcInputData[uiCurPlane][iSourcePos];
1437          }
1438          iXPos++;
1439        }
1440        }
1441      }
1442    }
1443
1444    // Fill Right Gap
1445    Int iXPosSearch = iWidth -1;
1446    while( (pcFilledData[iXPosSearch] == REN_IS_HOLE) && (iXPosSearch >= 0) ) iXPosSearch--;
1447    if ( iXPosSearch < 0) iXPosSearch++;
1448
1449    Int iSourcePos = iXPosSearch;
1450
1451    for( Int iXPos = iSourcePos + 1; iXPos <  iWidth; iXPos++)
1452        {
1453      for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1454          {
1455        apcOutputData[uiCurPlane][iXPos] = apcInputData[uiCurPlane][iSourcePos];
1456      }
1457            }
1458
1459    // Fill Left Gap
1460    iXPosSearch = 0;
1461    while( (pcFilledData[iXPosSearch] == REN_IS_HOLE) && (iXPosSearch < iWidth) ) iXPosSearch++;
1462    if ( iXPosSearch >= iWidth) iXPosSearch--;
1463
1464    iSourcePos = iXPosSearch;
1465
1466    for( Int iXPos = iSourcePos - 1; iXPos >= 0; iXPos--)
1467    {
1468      for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1469      {
1470        apcOutputData[uiCurPlane][iXPos] = apcInputData[uiCurPlane][iSourcePos];
1471          }
1472        }
1473
1474    // Go to next line
1475    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1476    {
1477      apcOutputData[uiCurPlane] += iOutputStride;
1478      apcInputData [uiCurPlane] += iInputStride;
1479    }
1480    pcFilledData += iFilledStride;
1481  }
1482  delete[] apcInputData;
1483  delete[] apcOutputData;
1484}
1485
1486Void TRenTop::xPostProcessImage(PelImage* pcInImage, PelImage* pcOutImage)
1487{
1488  if ( m_iPostProcMode == eRenPostProNone )
1489    return;
1490
1491  PelImage* pcTemp;
1492
1493  if (pcInImage == pcOutImage)
1494  {
1495    pcTemp = pcOutImage->create();
1496  }
1497  else
1498  {
1499    pcTemp = pcOutImage;
1500  }
1501
1502  pcTemp->assign(pcInImage);
1503
1504  switch ( m_iPostProcMode )
1505  {
1506  case eRenPostProMed:
1507    TRenFilter::lineMedian3(pcTemp);
1508    break;
1509  case eRenPostProNone:
1510    break;
1511  default:
1512    assert(0);
1513  }
1514
1515  if (pcInImage == pcOutImage)
1516  {
1517    pcOutImage->assign(pcTemp);
1518    delete pcTemp;
1519  };
1520}
1521
1522
1523Void TRenTop::xCutPlaneMargin( PelImagePlane* pcImagePlane, Pel cFill, UInt uiScale )
1524{
1525  UInt uiWidth  = pcImagePlane->getWidth();
1526  UInt uiHeight = pcImagePlane->getHeight();
1527
1528  UInt uiStride    = pcImagePlane->getStride();
1529  Pel* pcPlaneData = pcImagePlane->getPlaneData();
1530
1531  UInt uiCutLeft  =           m_auiCut[0] / uiScale;
1532  UInt uiCutRight = uiWidth - m_auiCut[1] / uiScale;
1533
1534  for(UInt uiYPos = 0; uiYPos < uiHeight; uiYPos++)
1535  {
1536    for(UInt uiXPos = 0; uiXPos < (UInt) uiWidth ; uiXPos++)
1537    {
1538      if ( ( uiXPos < uiCutLeft  )  || (  uiXPos >=  uiCutRight )  )
1539      {
1540        pcPlaneData[uiXPos ] = cFill;
1541      }
1542    }
1543    pcPlaneData += uiStride;
1544  }
1545};
1546
1547Void TRenTop::xCutMargin( PelImage* pcInputImage )
1548{
1549  if  ( ( m_auiCut[0] == 0 ) && ( m_auiCut[1] == 0 ) )
1550  {
1551    return;
1552  };
1553
1554  UInt uiCurPlane = 0;
1555  for (; uiCurPlane < pcInputImage->getNumberOfFullPlanes(); uiCurPlane++ )
1556  {
1557    xCutPlaneMargin( pcInputImage->getPlane(uiCurPlane), (Pel) 0  , 1 );
1558  }
1559
1560  for (; uiCurPlane < pcInputImage->getNumberOfPlanes(); uiCurPlane++ )
1561  {
1562    xCutPlaneMargin( pcInputImage->getPlane(uiCurPlane), (Pel) 128  , 2 );
1563  }
1564
1565};
1566
1567
1568Void TRenTop::xEnhSimilarity( PelImage* pcLeftImage, PelImage* pcRightImage, PelImage* pcFilledLeft, PelImage* pcFilledRight )
1569{
1570  if (m_iSimEnhBaseView == 0)
1571    return;
1572
1573  UInt uiNumFullPlanes = pcLeftImage->getNumberOfFullPlanes();
1574  UInt uiNumQuatPlanes = pcLeftImage->getNumberOfQuaterPlanes();
1575
1576  if (uiNumQuatPlanes > 0)
1577  {
1578    assert( pcFilledLeft ->getNumberOfPlanes() > 1);
1579    assert( pcFilledRight->getNumberOfPlanes() > 1);
1580  };
1581
1582  xEnhSimilarityPlane ( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), uiNumFullPlanes);
1583  if (uiNumQuatPlanes > 0)
1584  {
1585    xEnhSimilarityPlane ( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), uiNumQuatPlanes);
1586  }
1587}
1588
1589Void TRenTop::xEnhSimilarityPlane       ( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, UInt uiNumberOfPlanes )
1590{
1591  AOT( m_iSimEnhBaseView != 1 && m_iSimEnhBaseView != 2 );
1592  Int iWidth  = (*apcRightPlane)->getWidth ();
1593  Int iHeight = (*apcRightPlane)->getHeight();
1594
1595  Int* aiHistLeft  = new Int[ g_uiIBDI_MAX + 1 ];
1596  Int* aiHistRight = new Int[ g_uiIBDI_MAX + 1 ];
1597  Pel* aiConvLUT   = new Pel[ g_uiIBDI_MAX + 1 ];
1598
1599  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1600  {
1601    for (Int iCurVal = 0 ; iCurVal <= g_uiIBDI_MAX; iCurVal++)
1602    {
1603      aiHistLeft [iCurVal] = 0;
1604      aiHistRight[iCurVal] = 0;
1605    }
1606
1607    Pel* pcFilledRightData = pcFilledRightPlane    ->getPlaneData();
1608    Pel* pcRightImageData  = (*apcRightPlane )     ->getPlaneData();
1609
1610    Pel* pcFilledLeftData  = pcFilledLeftPlane     ->getPlaneData();
1611    Pel* pcLeftImageData   = (*apcLeftPlane)       ->getPlaneData();
1612
1613 
1614
1615    for (UInt uiYPos = 0; uiYPos < iHeight; uiYPos++ )
1616    {
1617      for (UInt uiXPos = 0; uiXPos < iWidth; uiXPos++ )
1618      {
1619          if      ( pcFilledLeftData[uiXPos] == REN_IS_FILLED &&  pcFilledRightData[uiXPos] == REN_IS_FILLED )
1620          {
1621            aiHistLeft [pcLeftImageData   [uiXPos] ]++;
1622            aiHistRight[pcRightImageData  [uiXPos] ]++;
1623          }
1624      }
1625
1626
1627      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1628      pcRightImageData  += (*apcRightPlane)       ->getStride();
1629
1630      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1631      pcLeftImageData   +=  (*apcLeftPlane)       ->getStride();
1632    }
1633
1634    Int iCumSumChange  = 0;
1635    Int iCumSumBase    = 0;
1636    Int iCurBaseVal    = 0;
1637    Int iCurChangeVal  = 0;
1638
1639    Int* aiHistChange  = (m_iSimEnhBaseView == 2 ) ? aiHistLeft  : aiHistRight;
1640    Int* aiHistBase    = (m_iSimEnhBaseView == 2 ) ? aiHistRight : aiHistLeft ;
1641
1642    iCumSumChange += aiHistChange[iCurChangeVal];
1643    iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1644
1645    Int iCheckSumLeft  = 0;
1646    Int iCheckSumRight = 0;
1647
1648    for (Int iCurVal = 0 ; iCurVal <= g_uiIBDI_MAX; iCurVal++)
1649    {
1650      iCheckSumLeft  += aiHistLeft [iCurVal];
1651      iCheckSumRight += aiHistRight[iCurVal];
1652    }
1653
1654
1655    while( iCurChangeVal <= g_uiIBDI_MAX )
1656    {
1657      if ( iCumSumBase == iCumSumChange )
1658      {
1659        aiConvLUT[iCurChangeVal] = Min(iCurBaseVal, g_uiIBDI_MAX);
1660        iCurBaseVal  ++;
1661        iCurChangeVal++;
1662        iCumSumChange += aiHistChange[iCurChangeVal];
1663        if (iCurBaseVal <= g_uiIBDI_MAX )
1664        {
1665          iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1666        }
1667      }
1668      else if ( iCumSumBase < iCumSumChange )
1669      {
1670        iCurBaseVal++;
1671        if (iCurBaseVal <= g_uiIBDI_MAX )
1672        {
1673          iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1674        }
1675      }
1676      else if ( iCumSumBase > iCumSumChange)
1677      {
1678        aiConvLUT[iCurChangeVal] = Min(iCurBaseVal, g_uiIBDI_MAX);
1679        iCurChangeVal++;
1680        iCumSumChange += aiHistChange  [iCurChangeVal]  ;
1681      }
1682    }
1683
1684    Pel* pcChangeImageData   = ( ( m_iSimEnhBaseView == 2 ) ? (*apcLeftPlane) : (*apcRightPlane) )->getPlaneData();
1685    Int  iChangeImageStride  = ( ( m_iSimEnhBaseView == 2 ) ? (*apcLeftPlane) : (*apcRightPlane) )->getStride   ();
1686
1687    for (UInt uiYPos = 0; uiYPos < iHeight; uiYPos++ )
1688    {
1689      for (UInt uiXPos = 0; uiXPos < iWidth; uiXPos++ )
1690      {
1691          pcChangeImageData  [uiXPos] = aiConvLUT[ pcChangeImageData[uiXPos]];
1692      }
1693      pcChangeImageData   +=  iChangeImageStride;
1694    }
1695
1696    apcRightPlane ++;
1697    apcLeftPlane  ++;
1698
1699  }
1700
1701delete[] aiHistLeft ;
1702delete[] aiHistRight;
1703delete[] aiConvLUT  ;
1704}
1705
1706
1707Void TRenTop::xBlend( PelImage* pcLeftImage, PelImage* pcRightImage, PelImage* pcFilledLeft, PelImage* pcFilledRight, PelImage* pcLeftDepth, PelImage* pcRightDepth, PelImage* pcOutputImage )
1708{
1709  UInt uiNumFullPlanes = pcLeftImage->getNumberOfFullPlanes();
1710  UInt uiNumQuatPlanes = pcLeftImage->getNumberOfQuaterPlanes();
1711
1712  assert( uiNumFullPlanes == pcRightImage->getNumberOfFullPlanes  () && uiNumFullPlanes == pcOutputImage->getNumberOfFullPlanes    ());
1713  assert( uiNumQuatPlanes == pcRightImage->getNumberOfQuaterPlanes() && uiNumQuatPlanes == pcOutputImage->getNumberOfQuaterPlanes  ());
1714
1715  if (uiNumQuatPlanes > 0)
1716  {
1717    assert( pcLeftDepth ->getNumberOfPlanes() > 1 || pcFilledLeft ->getNumberOfPlanes() > 1);
1718    assert( pcRightDepth->getNumberOfPlanes() > 1 || pcFilledRight->getNumberOfPlanes() > 1);
1719  };
1720
1721  switch (m_iBlendMode)
1722  {
1723  case eRenBlendAverg:
1724  case eRenBlendDepthFirst:
1725    xBlendPlanesAvg( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), pcLeftDepth->getPlane(0), pcRightDepth->getPlane(0), pcOutputImage->getPlanes(), uiNumFullPlanes);
1726    if (uiNumQuatPlanes > 0)
1727    {
1728      xBlendPlanesAvg( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), pcLeftDepth->getPlane(1), pcRightDepth->getPlane(1), pcOutputImage->getPlanes()+uiNumFullPlanes, uiNumQuatPlanes);
1729    }
1730    break;
1731  case eRenBlendLeft:
1732  case eRenBlendRight:
1733    xBlendPlanesOneView( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), pcLeftDepth->getPlane(0), pcRightDepth->getPlane(0), pcOutputImage->getPlanes(), uiNumFullPlanes);
1734    if (uiNumQuatPlanes > 0)
1735    {
1736      xBlendPlanesOneView( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), pcLeftDepth->getPlane(1), pcRightDepth->getPlane(1), pcOutputImage->getPlanes()+uiNumFullPlanes, uiNumQuatPlanes);
1737    }
1738    break;
1739  }
1740}
1741
1742Void TRenTop::xBlendPlanesOneView( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, PelImagePlane* pcLeftDepthPlane, PelImagePlane* pcRightDepthPlane, PelImagePlane** apcOutputImagePlane, UInt uiNumberOfPlanes )
1743{
1744  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1745  {
1746    Pel* pcFilledRightData = pcFilledRightPlane    ->getPlaneData();
1747    Pel* pcRightImageData  = (*apcRightPlane )     ->getPlaneData();
1748    Pel* pcRightDepthData  = pcRightDepthPlane     ->getPlaneData();
1749
1750    Pel* pcFilledLeftData  = pcFilledLeftPlane     ->getPlaneData();
1751    Pel* pcLeftImageData   = (*apcLeftPlane)       ->getPlaneData();
1752    Pel* pcLeftDepthData   = pcLeftDepthPlane      ->getPlaneData();
1753    Pel* pcOutputData      = (*apcOutputImagePlane)->getPlaneData();
1754
1755    for (UInt uiYPos = 0; uiYPos < (*apcOutputImagePlane)->getHeight(); uiYPos++ )
1756    {
1757      for (UInt uiXPos = 0; uiXPos < (*apcOutputImagePlane)->getWidth(); uiXPos++ )
1758      {
1759        if      (m_iBlendMode == eRenBlendLeft  )
1760        {
1761          if      ( pcFilledLeftData[uiXPos] == REN_IS_FILLED ||  pcFilledRightData[uiXPos] == REN_IS_HOLE )
1762          {
1763            pcOutputData[uiXPos] = pcLeftImageData[uiXPos];
1764          }
1765          else if ( pcFilledLeftData[uiXPos] == REN_IS_HOLE )
1766          {
1767            pcOutputData[uiXPos] = pcRightImageData[uiXPos];
1768          }
1769          else
1770          {
1771            pcOutputData[uiXPos] = pcRightImageData[uiXPos] +  (Pel) (  ( (Int) ( pcLeftImageData[uiXPos] - pcRightImageData[uiXPos] ) * pcFilledLeftData[uiXPos] + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1772          }
1773        }
1774        else if ( m_iBlendMode == eRenBlendRight )
1775        {
1776          if      ( pcFilledRightData[uiXPos] == REN_IS_FILLED || pcFilledLeftData[uiXPos] == REN_IS_HOLE )
1777          {
1778            pcOutputData[uiXPos] = pcRightImageData[uiXPos];
1779          }
1780          else if ( pcFilledRightData[uiXPos] == REN_IS_HOLE )
1781          {
1782            pcOutputData[uiXPos] = pcLeftImageData[uiXPos];
1783          }
1784          else
1785          {
1786            pcOutputData[uiXPos] = pcLeftImageData[uiXPos] +  (Pel) (  ( (Int) ( pcRightImageData[uiXPos] - pcLeftImageData[uiXPos] ) * pcFilledRightData[uiXPos] + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1787          }
1788        }
1789        else
1790        {
1791          AOT(true);
1792        }
1793      }
1794
1795      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1796      pcRightImageData  += (*apcRightPlane)       ->getStride();
1797      pcRightDepthData  +=    pcRightDepthPlane   ->getStride();
1798
1799      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1800      pcLeftImageData   +=  (*apcLeftPlane)       ->getStride();
1801      pcLeftDepthData   +=    pcLeftDepthPlane    ->getStride();
1802      pcOutputData      +=  (*apcOutputImagePlane)->getStride();
1803    }
1804
1805    apcRightPlane ++;
1806    apcLeftPlane  ++;
1807    apcOutputImagePlane++;
1808  }
1809}
1810
1811Void TRenTop::xBlendPlanesAvg( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, PelImagePlane* pcLeftDepthPlane, PelImagePlane* pcRightDepthPlane, PelImagePlane** apcOutputImagePlane, UInt uiNumberOfPlanes )
1812{
1813  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1814  {
1815    Pel* pcFilledRightData = pcFilledRightPlane   ->getPlaneData();
1816    Pel* pcRightVideoData  = (*apcRightPlane )    ->getPlaneData();
1817    Pel* pcRightDepthData  = pcRightDepthPlane    ->getPlaneData();
1818
1819    Pel* pcFilledLeftData  = pcFilledLeftPlane    ->getPlaneData();
1820    Pel* pcLeftVideoData   = (*apcLeftPlane)      ->getPlaneData();
1821    Pel* pcLeftDepthData   = pcLeftDepthPlane     ->getPlaneData();
1822
1823    Pel* pcOutputData      = (*apcOutputImagePlane)->getPlaneData();
1824
1825    for (UInt uiYPos = 0; uiYPos < (*apcOutputImagePlane)->getHeight(); uiYPos++ )
1826    {
1827      for (UInt uiXPos = 0; uiXPos < (*apcOutputImagePlane)->getWidth(); uiXPos++ )
1828      {
1829        if      (  (pcFilledRightData[uiXPos] != REN_IS_HOLE ) && ( pcFilledLeftData[uiXPos] != REN_IS_HOLE) )
1830        {
1831          Int iDepthDifference  = m_piInvZLUTLeft[RemoveBitIncrement(pcLeftDepthData[uiXPos])] - m_piInvZLUTRight[RemoveBitIncrement(pcRightDepthData[uiXPos])];
1832
1833          if ( abs ( iDepthDifference ) <= m_iBlendZThres )
1834          {
1835            if      ((pcFilledRightData[uiXPos] == REN_IS_FILLED) && ( pcFilledLeftData[uiXPos] != REN_IS_FILLED))
1836            {
1837              pcOutputData[uiXPos] = pcRightVideoData[uiXPos] +  (Pel) (  ( (Int) ( pcLeftVideoData[uiXPos] - pcRightVideoData[uiXPos] ) * (pcFilledLeftData[uiXPos]) + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1838            }
1839            else if ((pcFilledRightData[uiXPos] != REN_IS_FILLED) && ( pcFilledLeftData[uiXPos] == REN_IS_FILLED))
1840            {
1841              pcOutputData[uiXPos] = pcLeftVideoData[uiXPos]  +  (Pel) (  ( (Int) ( pcRightVideoData[uiXPos] - pcLeftVideoData[uiXPos] ) * (pcFilledRightData[uiXPos]) + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1842            }
1843            else
1844            {
1845              pcOutputData[uiXPos] = pcLeftVideoData[uiXPos]  +  (Pel) (  ( (Int) ( pcRightVideoData[uiXPos] - pcLeftVideoData[uiXPos] ) * m_iBlendDistWeight               + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1846            }
1847
1848          }
1849          else if ( iDepthDifference < 0 )
1850          {
1851            pcOutputData[uiXPos] = pcRightVideoData[uiXPos];
1852          }
1853          else
1854          {
1855            pcOutputData[uiXPos] = pcLeftVideoData[uiXPos];
1856          }
1857        }
1858        else if ( (pcFilledRightData[uiXPos] == REN_IS_HOLE) && (pcFilledLeftData[uiXPos] == REN_IS_HOLE))
1859        {
1860          pcOutputData[uiXPos] = m_piInvZLUTLeft[RemoveBitIncrement( pcLeftDepthData[uiXPos])]  < m_piInvZLUTRight[RemoveBitIncrement(pcRightDepthData[uiXPos])] ? pcLeftVideoData[uiXPos] : pcRightVideoData[uiXPos];
1861        }
1862        else
1863        {
1864          pcOutputData[uiXPos] =  (pcFilledLeftData[uiXPos] == REN_IS_HOLE) ? pcRightVideoData[uiXPos] : pcLeftVideoData[uiXPos];
1865        }
1866      }
1867
1868      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1869      pcRightVideoData  += (*apcRightPlane)      ->getStride();
1870      pcRightDepthData  +=    pcRightDepthPlane   ->getStride();
1871
1872      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1873      pcLeftVideoData   +=  (*apcLeftPlane)       ->getStride();
1874      pcLeftDepthData   +=    pcLeftDepthPlane    ->getStride();
1875      pcOutputData      +=  (*apcOutputImagePlane)->getStride();
1876    };
1877
1878    apcRightPlane ++;
1879    apcLeftPlane  ++;
1880    apcOutputImagePlane++;
1881  }
1882}
1883
1884// Temporal Filter from Zhejiang University: (a little different from m16041: Temporal Improvement Method in View Synthesis)
1885Void TRenTop::temporalFilterVSRS( TComPicYuv* pcPicYuvVideoCur, TComPicYuv* pcPicYuvDepthCur, TComPicYuv* pcPicYuvVideoLast, TComPicYuv* pcPicYuvDepthLast, Bool bFirstFrame )
1886{
1887  Int iSADThres  = 100 ;  //threshold of sad in 4*4 block motion detection
1888
1889  Int iWidth  = m_auiInputResolution[0];
1890  Int iHeight = m_auiInputResolution[1];
1891
1892  //internal variables
1893  Int* piFlagMoving =  m_aiBlkMoving + 2;
1894
1895  Int iVideoCurStride     = pcPicYuvVideoCur ->getStride();
1896  Int iVideoLastStride    = pcPicYuvVideoLast->getStride();
1897  Int iDepthCurStride     = pcPicYuvDepthCur ->getStride();
1898  Int iDepthLastStride    = pcPicYuvDepthLast->getStride();
1899
1900  Pel* pcVideoCurData     = pcPicYuvVideoCur ->getLumaAddr();
1901  Pel* pcVideoLastData    = pcPicYuvVideoLast->getLumaAddr();
1902  Pel* pcDepthCurData     = pcPicYuvDepthCur ->getLumaAddr();
1903  Pel* pcDepthLastData    = pcPicYuvDepthLast->getLumaAddr();
1904
1905  Pel* pcVideoCurDataFrm  = pcVideoCurData ;
1906  Pel* pcVideoLastDataFrm = pcVideoLastData;
1907  Pel* pcDepthCurDataFrm  = pcDepthCurData ;
1908  Pel* pcDepthLastDataFrm = pcDepthLastData;
1909
1910
1911  if( !bFirstFrame ) // first frame need not the weighting, but need to prepare the data
1912  {
1913    for ( Int iPosY = 0; iPosY < (iHeight >> 2); iPosY++)
1914    {
1915      //motion detection by SAD
1916      for ( Int iPosX = 0; iPosX < (iWidth >> 2);  iPosX++)
1917      {
1918        Int iSAD = 0;
1919
1920        Pel* pcVideoCurDataBlk  = pcVideoCurDataFrm  + (iPosX << 2);
1921        Pel* pcVideoLastDataBlk = pcVideoLastDataFrm + (iPosX << 2);
1922
1923        //GT: Check difference of block compared to last frame
1924        for( Int iCurPosY = 0; iCurPosY < 4; iCurPosY++)
1925        {
1926          for( Int iCurPosX = 0; iCurPosX < 4; iCurPosX++)
1927          {
1928            iSAD += abs( pcVideoLastDataBlk[iCurPosX] - pcVideoCurDataBlk[iCurPosX] );   //SAD
1929          }
1930          pcVideoLastDataBlk += iVideoLastStride;
1931          pcVideoCurDataBlk  += iVideoCurStride;
1932        }
1933
1934        piFlagMoving[iPosX] = ( iSAD < iSADThres ) ? 0 : 1;
1935      }
1936
1937      //temporal weighting according to motion detection result -- do a line
1938      for ( Int iPosX = 0; iPosX < (iWidth >> 2);  iPosX++)
1939      {
1940        //5 block
1941       Int iSumMoving = piFlagMoving[iPosX-2] + piFlagMoving[iPosX-1] + piFlagMoving[iPosX]   + piFlagMoving[iPosX+1] + piFlagMoving[iPosX+2];
1942
1943        if( iSumMoving == 0 ) // if not moving
1944        {
1945          Pel* pcDepthCurDataBlk  = pcDepthCurDataFrm  + (iPosX << 2);
1946          Pel* pcDepthLastDataBlk = pcDepthLastDataFrm + (iPosX << 2);
1947
1948          for( Int iCurPosY = 0; iCurPosY < 4; iCurPosY++)
1949          {
1950            for( Int iCurPosX = 0; iCurPosX < 4; iCurPosX++)
1951            { //Weight: 0.75
1952              Int iFilt = (( (pcDepthLastDataBlk[iCurPosX] << 1 ) + pcDepthLastDataBlk[iCurPosX] + pcDepthCurDataBlk[iCurPosX] + 2 ) >> 2 );
1953              assert( (iFilt >= 0) && (iFilt <=  g_uiIBDI_MAX) );
1954              pcDepthCurDataBlk[iCurPosX] = pcDepthLastDataBlk[iCurPosX];
1955              pcDepthCurDataBlk[iCurPosX] = iFilt;
1956            }
1957
1958            pcDepthCurDataBlk  += iDepthCurStride;
1959            pcDepthLastDataBlk += iDepthLastStride;
1960          }
1961        }
1962      }
1963
1964      pcDepthCurDataFrm  += ( iDepthCurStride  << 2);
1965      pcDepthLastDataFrm += ( iDepthLastStride << 2);
1966      pcVideoCurDataFrm  += ( iVideoCurStride  << 2);
1967      pcVideoLastDataFrm += ( iVideoLastStride << 2);
1968    }
1969  }
1970  pcPicYuvVideoCur->copyToPic( pcPicYuvVideoLast );
1971  pcPicYuvDepthCur->copyToPic( pcPicYuvDepthLast );
1972}
1973
1974TRenTop::TRenTop()
1975{
1976  m_auiInputResolution[0] = 0;
1977  m_auiInputResolution[1] = 0;
1978
1979  // Sub Pel Rendering
1980  m_iLog2SamplingFactor = 0;
1981
1982  // ColorPlaneHandling
1983  m_bUVUp = true;
1984
1985
1986  //PreProcessing
1987  m_iPreProcMode         = eRenPreProNone;
1988  m_iPreFilterSize = 2;
1989
1990  // Interpolation
1991  m_iInterpolationMode   = eRenIntFullPel;
1992
1993  // Sim Enhancement
1994  m_iSimEnhBaseView      = 0;
1995
1996  // Blending
1997  m_iBlendMode           = eRenBlendAverg;
1998  m_iBlendZThresPerc     = -1;
1999  m_bBlendUseDistWeight  = false;
2000  m_iBlendHoleMargin     = -1;
2001
2002  m_iBlendZThres         = -1;
2003  m_iBlendDistWeight     = -1;
2004
2005  // Hole Filling
2006  m_iHoleFillingMode     = eRenHFLWBackExt;
2007  m_bInstantHoleFilling  = false;
2008
2009  // PostProcessing
2010  m_iPostProcMode        = eRenPostProNone;
2011
2012  // Cut
2013  m_auiCut[0] = 0;
2014  m_auiCut[1] = 0;
2015
2016  // Data
2017  m_uiSampledWidth = -1;
2018
2019  // LUTs
2020  m_ppdShiftLUTLeft  = 0;
2021  m_ppdShiftLUTRight = 0;
2022
2023  m_ppdShiftLUTRightMirror    = new Double*[2];
2024  m_ppdShiftLUTRightMirror[0] = new Double [257];
2025  m_ppdShiftLUTRightMirror[1] = new Double [257];
2026
2027  m_adShiftLUTCur    = 0;
2028
2029  m_ppiShiftLUTLeft  = 0;
2030  m_ppiShiftLUTRight = 0;
2031  m_ppiShiftLUTRightMirror    = new Int*[2];
2032  m_ppiShiftLUTRightMirror[0] = new Int[257];
2033  m_ppiShiftLUTRightMirror[1] = new Int[257];
2034
2035  m_aiShiftLUTCur    = 0;
2036  m_piInvZLUTLeft  = new Int[257];
2037  m_piInvZLUTRight = new Int[257];
2038
2039  // Buffers
2040  m_pcLeftInputImage   = 0;
2041  m_pcLeftInputDepth   = 0;
2042  m_pcLeftOutputImage  = 0;
2043  m_pcLeftOutputDepth  = 0;
2044  m_pcLeftFilled       = 0;
2045
2046  m_pcRightInputImage  = 0;
2047  m_pcRightInputDepth  = 0;
2048  m_pcRightOutputImage = 0;
2049  m_pcRightOutputDepth = 0;
2050  m_pcRightFilled      = 0;
2051
2052  m_pcOutputImage      = 0;
2053  m_pcOutputDepth      = 0;
2054
2055  //Extrapolation
2056  m_pcInputImage       = 0;
2057  m_pcInputDepth       = 0;
2058  m_pcFilled           = 0;
2059
2060  // SubPel
2061  m_aaiSubPelShift     = 0;
2062
2063  // Temp
2064  m_pcTempImage        = 0;
2065
2066  //Temporal Filter
2067  m_aiBlkMoving        = 0;
2068}
2069
2070
2071Void TRenTop::init(UInt uiImageWidth,
2072                   UInt uiImageHeight,
2073                   Bool  bExtrapolate,
2074                   UInt uiLog2SamplingFactor,
2075                   Int   iShiftLUTPrec,
2076                   Bool  bUVUp,
2077                   Int   iPreProcMode,
2078                   Int   iPreFilterKernelSize,
2079                   Int   iBlendMode,
2080                   Int   iBlendZThresPerc,
2081                   Bool  bBlendUseDistWeight,
2082                   Int   iBlendHoleMargin,
2083                   Int   iInterpolationMode,
2084                   Int   iHoleFillingMode,
2085                   Int   iPostProcMode,
2086                   Int   iUsedPelMapMarExt
2087                   )
2088
2089{
2090  // Shift LUT Prec
2091  m_iRelShiftLUTPrec = iShiftLUTPrec - (Int) uiLog2SamplingFactor;
2092
2093  // Sub Pel Rendering
2094  m_iLog2SamplingFactor = uiLog2SamplingFactor;
2095
2096  // Extrapolation ?
2097  m_bExtrapolate = bExtrapolate;
2098
2099  // ColorPlaneHandling
2100  m_bUVUp = bUVUp;
2101
2102  //PreProcessing
2103  m_iPreProcMode = iPreProcMode;
2104  m_iPreFilterSize = iPreFilterKernelSize;
2105
2106  // Interpolation
2107  m_iInterpolationMode = iInterpolationMode;
2108
2109  //Blending
2110  m_iBlendMode          = iBlendMode;
2111  m_iBlendZThresPerc    = iBlendZThresPerc;
2112  m_bBlendUseDistWeight = bBlendUseDistWeight;
2113  m_iBlendHoleMargin    = iBlendHoleMargin;
2114
2115  // Hole Filling
2116  m_iHoleFillingMode = iHoleFillingMode;
2117
2118  m_bInstantHoleFilling   = (m_iInterpolationMode == eRenInt8Tap ) && (m_iHoleFillingMode != 0 );
2119
2120  // PostProcessing
2121  m_iPostProcMode    = iPostProcMode;
2122
2123  // Used pel map
2124  m_iUsedPelMapMarExt     = iUsedPelMapMarExt;
2125
2126  // Cut
2127  m_auiCut[0] = 0;
2128  m_auiCut[1] = 0;
2129
2130  m_auiInputResolution[0] = uiImageWidth;
2131  m_auiInputResolution[1] = uiImageHeight;
2132
2133  if ( m_bExtrapolate )
2134  {
2135    PelImage*    pcDump        = 0;
2136    xGetDataPointers( m_pcInputImage, m_pcOutputImage, m_pcInputDepth, pcDump, m_pcFilled, false );
2137  }
2138  else
2139  {
2140    xGetDataPointers(m_pcLeftInputImage,  m_pcLeftOutputImage,  m_pcLeftInputDepth,  m_pcLeftOutputDepth,  m_pcLeftFilled,  true);
2141    xGetDataPointers(m_pcRightInputImage, m_pcRightOutputImage, m_pcRightInputDepth, m_pcRightOutputDepth, m_pcRightFilled, true);
2142    xGetDataPointerOutputImage(m_pcOutputImage, m_pcOutputDepth );
2143  }
2144
2145  m_pcTempImage = new PelImage( m_auiInputResolution[0],m_auiInputResolution[1],1,2);
2146
2147  // SubPelShiftLUT
2148  if (iInterpolationMode == eRenInt8Tap)
2149  {
2150    // SubPel Shift LUT
2151    Int iNumEntries = (1 << ( m_iRelShiftLUTPrec + 1) ) + 1 ;
2152    m_aaiSubPelShift = new Int*[ iNumEntries ];
2153    for (UInt uiEntry = 0; uiEntry < iNumEntries; uiEntry++)
2154    {
2155      m_aaiSubPelShift[uiEntry] = new Int[ iNumEntries ];
2156        }
2157
2158    TRenFilter::setSubPelShiftLUT(m_iRelShiftLUTPrec, m_aaiSubPelShift, -1);
2159  }
2160
2161  // Zheijang temporal filter
2162  m_aiBlkMoving    = new Int[ ( m_auiInputResolution[0] >> 2 ) + 4 ];
2163  m_aiBlkMoving[0] = 0;
2164  m_aiBlkMoving[1] = 0;
2165  m_aiBlkMoving[ ( m_auiInputResolution[0] >> 2 ) + 2 ] = 0;
2166  m_aiBlkMoving[ ( m_auiInputResolution[0] >> 2 ) + 3 ] = 0;
2167}
2168
2169
2170TRenTop::~TRenTop()
2171{
2172  if ( m_ppdShiftLUTRightMirror != NULL )
2173  {
2174    delete[] m_ppdShiftLUTRightMirror[0];
2175    delete[] m_ppdShiftLUTRightMirror[1];
2176    delete[] m_ppdShiftLUTRightMirror;
2177  };
2178
2179  if ( m_ppiShiftLUTRightMirror != NULL )
2180  {
2181    delete[] m_ppiShiftLUTRightMirror[0];
2182    delete[] m_ppiShiftLUTRightMirror[1];
2183    delete[] m_ppiShiftLUTRightMirror;
2184  };
2185
2186  if (m_piInvZLUTLeft      != NULL ) delete[] m_piInvZLUTLeft   ;
2187  if (m_piInvZLUTLeft      != NULL ) delete[] m_piInvZLUTRight  ;
2188
2189  if (m_pcLeftInputImage   != NULL ) delete m_pcLeftInputImage  ;
2190  if (m_pcLeftInputDepth   != NULL ) delete m_pcLeftInputDepth  ;
2191  if (m_pcLeftOutputImage  != NULL ) delete m_pcLeftOutputImage ;
2192  if (m_pcLeftOutputDepth  != NULL ) delete m_pcLeftOutputDepth ;
2193  if (m_pcLeftFilled       != NULL ) delete m_pcLeftFilled      ;
2194
2195  if (m_pcRightInputImage  != NULL ) delete m_pcRightInputImage ;
2196  if (m_pcRightInputDepth  != NULL ) delete m_pcRightInputDepth ;
2197  if (m_pcRightOutputImage != NULL ) delete m_pcRightOutputImage;
2198  if (m_pcRightOutputDepth != NULL ) delete m_pcRightOutputDepth;
2199  if (m_pcRightFilled      != NULL ) delete m_pcRightFilled     ;
2200
2201  if (m_pcOutputImage      != NULL ) delete m_pcOutputImage     ;
2202  if (m_pcOutputDepth      != NULL ) delete m_pcOutputDepth     ;
2203
2204  if (m_pcInputImage       != NULL ) delete m_pcInputImage      ;
2205  if (m_pcInputDepth       != NULL ) delete m_pcInputDepth      ;
2206  if (m_pcFilled           != NULL ) delete m_pcFilled          ;
2207
2208  if (m_pcTempImage        != NULL ) delete m_pcTempImage       ;
2209
2210  // SubPel LUT
2211  if ( m_aaiSubPelShift != NULL)
2212  {
2213    Int iNumEntries = (1 << ( m_iRelShiftLUTPrec + 1) ) + 1;
2214    for (UInt uiEntry = 0; uiEntry < iNumEntries; uiEntry++)
2215    {
2216      delete[] m_aaiSubPelShift[uiEntry];
2217    }
2218    delete[] m_aaiSubPelShift;
2219  }
2220
2221  // Zheijang temporal filter
2222  if(m_aiBlkMoving         != NULL ) delete[] m_aiBlkMoving;
2223}
Note: See TracBrowser for help on using the repository browser.