source: 3DVCSoftware/branches/HTM-DEV-2.0-dev2-MediaTek/source/Lib/TLibRenderer/TRenTop.cpp @ 563

Last change on this file since 563 was 499, checked in by zhang, 12 years ago

Changes include: DV-MVP(H_3D_IDV), TMVP merging candidate(H_3D_TMVP, target reference index changes, scaling based on view order index) and cleanups (H_3D_CLEANUPS)

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