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

Last change on this file since 608 was 608, checked in by tech, 11 years ago

Merged DEV-2.0-dev0@604.

  • Property svn:eol-style set to native
File size: 79.6 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#if H_3D_FIX_REN
1036              if ( ( iInterPolPos >= 0 ) && ( iInterPolPos < iOutputWidth ) )
1037              {
1038                if( pcFilledData[iInterPolPos] == REN_IS_HOLE )
1039                {               
1040                  Int iNextPos = std::min(iInputWidth-1,iPosX + iStep); 
1041                  Int iPosXBG  = ( std::abs( pcDepthData[iNextPos] - pcDepthData[iPosX] ) > 5  ) ? iPosX : iNextPos; 
1042                  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1043                  {
1044                    apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosXBG];
1045                  }
1046                }
1047                else
1048                {
1049                  pcFilledData[iInterPolPos] = REN_IS_HOLE + 1; 
1050                }
1051              }
1052#else
1053              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1054              {
1055                if ( ( iInterPolPos >= 0 ) && ( iInterPolPos < iOutputWidth ) )
1056                {
1057                  apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX];
1058                }
1059              }
1060#endif
1061            }
1062          }
1063        }
1064
1065        //// Last sample next to occlusion
1066        Int iShiftedPosFloor = ( iShiftedPos >> m_iRelShiftLUTPrec ) << m_iRelShiftLUTPrec;
1067        if ( bOcclusion && (iShiftedPos - (iStep >> 1) < iShiftedPosFloor) )
1068        {
1069          iInterPolPos = iShiftedPosFloor >> m_iRelShiftLUTPrec;
1070          if ( !((iInterPolPos < (Int) 0) || (iInterPolPos >= iOutputWidth)))
1071          {       
1072            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1073            {
1074              apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX ];
1075            }
1076
1077            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
1078          }
1079        }
1080      }
1081      iPrevShiftedPos = iShiftedPos;
1082    }
1083
1084    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1085    {
1086      apcOutputData[uiCurPlane] += iOutputStride;
1087      apcInputData [uiCurPlane] += iInputStride;
1088    }
1089    pcFilledData += iFilledStride;
1090    pcDepthData  += iDepthStride;
1091  }
1092  delete[] apcInputData;
1093  delete[] apcOutputData;
1094};
1095
1096Void TRenTop::xShiftPixels(PelImage* pcInImage, PelImage* pcDepth, PelImage* pcOutImage, PelImage* pcFilledImage, Bool bShiftFromLeft )
1097{
1098  PelImage*  pcTemp = 0;
1099
1100  if (pcInImage == pcOutImage)
1101  {
1102    pcTemp = pcOutImage->create();
1103  }
1104  else
1105  {
1106    pcTemp = pcOutImage;
1107  }
1108
1109  Double ** ppdShiftLUT = bShiftFromLeft ? m_ppdShiftLUTLeft : m_ppdShiftLUTRightMirror;
1110  Int    ** ppiShiftLUT = bShiftFromLeft ? m_ppiShiftLUTLeft : m_ppiShiftLUTRightMirror;
1111
1112  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1113  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1114
1115  assert( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1116  assert( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1117
1118  m_aiShiftLUTCur = ppiShiftLUT[ 0 ];
1119  m_adShiftLUTCur = ppdShiftLUT[ 0 ];
1120
1121  xShiftPlanePixels( pcInImage->getPlanes(), pcDepth->getPlane(0),  pcOutImage->getPlanes(), pcFilledImage->getPlane(0),  uiNumFullPlanes  );
1122
1123  if (uiNumQuatPlanes > 0)
1124  {
1125    assert( pcDepth->getNumberOfPlanes() > 1 && pcFilledImage->getNumberOfPlanes() > 1);
1126    m_aiShiftLUTCur = ppiShiftLUT[ 1 ];
1127    m_adShiftLUTCur = ppdShiftLUT[ 1 ];
1128    xShiftPlanePixels( pcInImage->getPlanes()+uiNumFullPlanes,pcDepth->getPlane(1),  pcOutImage->getPlanes() + uiNumFullPlanes, pcFilledImage->getPlane(1),  uiNumQuatPlanes );
1129  }
1130
1131  if (pcInImage == pcOutImage)
1132  {
1133    pcOutImage->assign(pcTemp);
1134    delete pcTemp;
1135  };
1136};
1137
1138Void TRenTop::xBackShiftPixels(PelImage* pcInImage, PelImage* pcDepth, PelImage* pcOutImage, PelImage* pcFilledImage, Bool bShiftFromLeft )
1139{
1140  PelImage*  pcTemp = 0;
1141
1142  if (pcInImage == pcOutImage)
1143  {
1144    pcTemp = pcOutImage->create();
1145  }
1146  else
1147  {
1148    pcTemp = pcOutImage;
1149  }
1150
1151  Double ** ppdShiftLUT = bShiftFromLeft ? m_ppdShiftLUTLeft : m_ppdShiftLUTRight;
1152  Int    ** ppiShiftLUT = bShiftFromLeft ? m_ppiShiftLUTLeft : m_ppiShiftLUTRight;
1153
1154  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1155  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1156
1157  assert( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1158  assert( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1159
1160  m_aiShiftLUTCur = ppiShiftLUT[ 0 ];
1161  m_adShiftLUTCur = ppdShiftLUT[ 0 ];
1162
1163  xBackShiftPlanePixels( pcInImage->getPlanes(), pcDepth->getPlane(0),  pcOutImage->getPlanes(), pcFilledImage->getPlane(0),  uiNumFullPlanes  );
1164
1165  if (uiNumQuatPlanes > 0)
1166  {
1167    assert( pcDepth->getNumberOfPlanes() > 1 && pcFilledImage->getNumberOfPlanes() > 1);
1168    m_aiShiftLUTCur = ppiShiftLUT[ 1 ];
1169    m_adShiftLUTCur = ppdShiftLUT[ 1 ];
1170    xBackShiftPlanePixels( pcInImage->getPlanes()+uiNumFullPlanes,pcDepth->getPlane(1),  pcOutImage->getPlanes() + uiNumFullPlanes, pcFilledImage->getPlane(1),  uiNumQuatPlanes );
1171  }
1172
1173  if (pcInImage == pcOutImage)
1174  {
1175    pcOutImage->assign(pcTemp);
1176    delete pcTemp;
1177  };
1178};
1179
1180Void TRenTop::xFillHoles(PelImage* pcInImage, PelImage* pcFilled, PelImage* pcOutImage, Bool bRenderFromLeft )
1181{
1182  if (pcInImage != pcOutImage)
1183  {
1184    pcOutImage->assign(pcInImage);
1185  }
1186
1187  switch (m_iHoleFillingMode)
1188  {
1189    case eRenHFNone:
1190      break;
1191    case eRenHFLWBackExt:
1192      xFillLWBackExt( pcInImage, pcFilled, pcOutImage, bRenderFromLeft);
1193      break;
1194    default:
1195      break;
1196  }
1197};
1198
1199Void TRenTop::xFillLWBackExt( PelImage* pcInImage, PelImage* pcFilledImage, PelImage* pcOutImage, Bool bRenderFromLeft )
1200{
1201  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1202  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1203
1204  assert( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1205  assert( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1206
1207  xFillPlaneHoles( pcInImage->getPlanes(), pcFilledImage->getPlane(0), pcOutImage->getPlanes(),  uiNumFullPlanes, bRenderFromLeft  );
1208
1209  if (uiNumQuatPlanes > 0)
1210  {
1211    assert(  pcFilledImage->getNumberOfPlanes() > 1);
1212    xFillPlaneHoles( pcInImage->getPlanes()+uiNumFullPlanes, pcFilledImage->getPlane(1), pcOutImage->getPlanes() + uiNumFullPlanes,  uiNumQuatPlanes, bRenderFromLeft );
1213  }
1214};
1215
1216Void TRenTop::xCreateAlphaMap(PelImage* pcFilledImage, PelImage* pcAlphaMapImage, Bool bRenderFromLeft )
1217{
1218  UInt uiNumFullPlanes = pcFilledImage  ->getNumberOfFullPlanes();
1219  UInt uiNumQuatPlanes = pcFilledImage->getNumberOfQuaterPlanes();
1220
1221  AOF( uiNumFullPlanes == pcAlphaMapImage->getNumberOfFullPlanes  () );
1222  AOF( uiNumQuatPlanes == pcAlphaMapImage->getNumberOfQuaterPlanes() );
1223
1224  xCreateAlphaMapPlane( pcFilledImage->getPlanes(),  pcAlphaMapImage->getPlanes(),  uiNumFullPlanes, bRenderFromLeft  );
1225
1226  if (uiNumQuatPlanes > 0)
1227  {
1228    AOF(  pcFilledImage->getNumberOfPlanes() > 1);
1229    xCreateAlphaMapPlane( pcFilledImage->getPlanes()+ uiNumFullPlanes, pcAlphaMapImage->getPlanes()+uiNumFullPlanes,  uiNumQuatPlanes, bRenderFromLeft );
1230  }
1231};
1232
1233Void TRenTop::xCreateAlphaMapPlane(PelImagePlane** apcFilledPlanes,  PelImagePlane** apcAlphaPlanes,  UInt uiNumberOfPlanes, Bool bRenderFromLeft)
1234{
1235  Int iWidth            = apcFilledPlanes [0]->getWidth();
1236  Int iHeight           = apcFilledPlanes [0]->getHeight();
1237
1238  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1239  {
1240    AOF( iWidth         == apcFilledPlanes [uiCurPlane]->getWidth()  && iWidth        == apcAlphaPlanes[uiCurPlane]->getWidth() );
1241    AOF( iHeight        == apcFilledPlanes [uiCurPlane]->getHeight() && iHeight       == apcAlphaPlanes[uiCurPlane]->getHeight());
1242  }
1243
1244  Int iBlendWidth  = m_iBlendHoleMargin;
1245  Int iMaxBlendLevel;
1246
1247  if (!m_bBlendUseDistWeight )
1248  {
1249    iMaxBlendLevel = ( 1 <<  REN_VDWEIGHT_PREC ) ;
1250
1251    if ( m_iBlendMode == 0)
1252    {
1253      iMaxBlendLevel >>= 1;
1254    }
1255  }
1256  else
1257  {
1258    if ( m_iBlendMode == 0)
1259    {
1260      iMaxBlendLevel = bRenderFromLeft ? (1 << REN_VDWEIGHT_PREC) - m_iBlendDistWeight :  m_iBlendDistWeight;
1261    }
1262    else
1263    {
1264      iMaxBlendLevel  = ( 1 <<  REN_VDWEIGHT_PREC );
1265    }
1266  }
1267
1268  Int iWeightStep = (iBlendWidth > 0) ? ( iMaxBlendLevel + (iBlendWidth >> 1) ) / iBlendWidth : 0;
1269
1270  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1271  {
1272    Int iFilledStride   = apcFilledPlanes [uiCurPlane]->getStride();
1273    Int iAlphaStride    = apcAlphaPlanes  [uiCurPlane]->getStride();
1274
1275    Pel* pcFilledData = apcFilledPlanes   [uiCurPlane]->getPlaneData();
1276    Pel* pcAlphaData  = apcAlphaPlanes    [uiCurPlane]->getPlaneData();
1277
1278    for(Int iYPos = 0; iYPos < iHeight; iYPos++)
1279    {
1280      for(Int iXPos = 0 ; iXPos < iWidth; iXPos++ )
1281      {
1282        if (pcFilledData[iXPos] == REN_IS_HOLE)
1283        {
1284          while( (pcFilledData[iXPos] == REN_IS_HOLE) && (iXPos < iWidth) )
1285          {
1286            pcAlphaData[iXPos] = REN_IS_HOLE;
1287            iXPos++;
1288          }
1289
1290          if ( iXPos >= iWidth )
1291            continue;
1292
1293          Int iWeight = 0;
1294          Int iLastFillPos = iXPos + iBlendWidth;
1295
1296          while( (pcFilledData[iXPos] != REN_IS_HOLE) && (iXPos < iWidth) && (iXPos < iLastFillPos) )
1297          {
1298            AOF(  iWeight <= (1 << REN_VDWEIGHT_PREC) );
1299            pcAlphaData[iXPos]  = (iWeight == 0) ? 1 : iWeight;
1300            iWeight += iWeightStep;
1301            iXPos++;
1302          }
1303        }
1304        else
1305        {
1306#if H_3D_FIX_REN
1307          pcAlphaData[iXPos] = pcFilledData[iXPos];
1308#else
1309          pcAlphaData[iXPos] = REN_IS_FILLED;
1310#endif
1311        }
1312      }
1313      pcAlphaData    += iAlphaStride;
1314      pcFilledData   += iFilledStride;
1315    }
1316  }
1317}
1318
1319Void TRenTop::xRemBoundaryNoise(PelImage* pcInImage, PelImage* pcFilledImage, PelImage* pcOutImage, Bool bRenderFromLeft )
1320{
1321  if (pcInImage != pcOutImage)
1322  {
1323    pcOutImage->assign(pcInImage);
1324  }
1325
1326  UInt uiNumFullPlanes = pcInImage->getNumberOfFullPlanes();
1327  UInt uiNumQuatPlanes = pcInImage->getNumberOfQuaterPlanes();
1328
1329  AOF( uiNumFullPlanes == pcOutImage->getNumberOfFullPlanes  () );
1330  AOF( uiNumQuatPlanes == pcOutImage->getNumberOfQuaterPlanes() );
1331
1332  xRemBoundaryNoisePlane( pcInImage->getPlanes(), pcFilledImage->getPlane(0), pcOutImage->getPlanes(),  uiNumFullPlanes, bRenderFromLeft  );
1333
1334  if (uiNumQuatPlanes > 0)
1335  {
1336    AOF(  pcFilledImage->getNumberOfPlanes() > 1);
1337    xRemBoundaryNoisePlane( pcInImage->getPlanes()+uiNumFullPlanes, pcFilledImage->getPlane(1), pcOutImage->getPlanes() + uiNumFullPlanes,  uiNumQuatPlanes, bRenderFromLeft );
1338  }
1339};
1340
1341Void TRenTop::xRemBoundaryNoisePlane(PelImagePlane** apcInputPlanes,  PelImagePlane* pcFilledPlane, PelImagePlane** apcOutputPlanes, UInt uiNumberOfPlanes, Bool bRenderFromLeft)
1342{
1343  Int iWidth        = apcOutputPlanes[0]->getWidth();
1344  Int iHeight       = apcInputPlanes [0]->getHeight();
1345
1346  Int iInputStride  = apcInputPlanes [0]->getStride();
1347  Int iOutputStride = apcOutputPlanes[0]->getStride();
1348
1349  Int iFilledStride = pcFilledPlane->getStride();
1350
1351  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
1352  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
1353  Pel*   pcFilledData = pcFilledPlane->getPlaneData();
1354
1355  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1356  {
1357    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
1358    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
1359    AOF( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
1360    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
1361    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
1362  }
1363
1364  Int iRemovalWidth  = m_iBlendHoleMargin;
1365  AOT(iRemovalWidth > 6);  // GT: insufficent padding
1366
1367  for(Int iYPos = 0; iYPos < iHeight; iYPos++)
1368  {
1369    for(Int iXPos = iWidth-1; iXPos >= 0; iXPos-- )
1370    {
1371      if (pcFilledData[iXPos] == REN_IS_HOLE)
1372      {
1373        Int iSourcePos = iXPos + 1;
1374
1375        // Get New Value
1376        while( (pcFilledData[iSourcePos] != REN_IS_HOLE) && ( iSourcePos < iWidth) && ( iSourcePos < iXPos + iRemovalWidth  ) ) iSourcePos++;
1377
1378        if (iSourcePos == iWidth || pcFilledData[iSourcePos] != REN_IS_HOLE )
1379          iSourcePos--;
1380
1381        Int iXPosRem = iSourcePos - 1;
1382
1383        // Remove
1384        while( iXPosRem > iXPos)
1385        {
1386          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1387          {
1388            apcOutputData[uiCurPlane][iXPosRem] = apcInputData[uiCurPlane][iSourcePos];
1389          }
1390
1391          iXPosRem--;
1392        }
1393
1394        // Skip Hole
1395        while( (pcFilledData[iXPos] == REN_IS_HOLE) && ( iXPos > 0) ) iXPos--;
1396      }
1397    }
1398
1399    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1400    {
1401      apcOutputData[uiCurPlane] += iOutputStride;
1402      apcInputData [uiCurPlane] += iInputStride;
1403    }
1404    pcFilledData += iFilledStride;
1405  }
1406  delete[] apcInputData;
1407  delete[] apcOutputData;
1408}
1409
1410Void TRenTop::xFillPlaneHoles(PelImagePlane** apcInputPlanes,  PelImagePlane* pcFilledPlane, PelImagePlane** apcOutputPlanes, UInt uiNumberOfPlanes, Bool bRenderFromLeft)
1411{
1412  Int iWidth        = apcOutputPlanes[0]->getWidth();
1413  Int iHeight       = apcInputPlanes [0]->getHeight();
1414
1415  Int iInputStride  = apcInputPlanes [0]->getStride();
1416  Int iOutputStride = apcOutputPlanes[0]->getStride();
1417
1418  Int iFilledStride = pcFilledPlane->getStride();
1419
1420  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
1421  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
1422  Pel*   pcFilledData = pcFilledPlane->getPlaneData();
1423
1424  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1425  {
1426    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
1427    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
1428    AOF( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
1429    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
1430    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
1431  }
1432
1433  for(Int iYPos = 0; iYPos < iHeight; iYPos++)
1434  {
1435    if ( !m_bInstantHoleFilling )
1436    {
1437    for(Int iXPos = 0 ; iXPos < iWidth; iXPos++ )
1438    {
1439      if (pcFilledData[iXPos] == REN_IS_HOLE)
1440      {
1441          Int iSourcePos;
1442          Int iLastFillPos;
1443
1444        Int iXPosSearch = iXPos;
1445        while( (pcFilledData[iXPosSearch] == REN_IS_HOLE) && (iXPosSearch < iWidth) ) iXPosSearch++;
1446
1447          if ( iXPosSearch >= iWidth )
1448        {
1449            continue;
1450          }
1451          else
1452          {
1453            iSourcePos   = iXPosSearch;
1454            iLastFillPos = iXPosSearch-1;
1455          }
1456
1457        while( iXPos <= iLastFillPos)
1458        {
1459          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1460          {
1461            apcOutputData[uiCurPlane][iXPos] = apcInputData[uiCurPlane][iSourcePos];
1462          }
1463          iXPos++;
1464        }
1465        }
1466      }
1467    }
1468
1469    // Fill Right Gap
1470    Int iXPosSearch = iWidth -1;
1471    while( (pcFilledData[iXPosSearch] == REN_IS_HOLE) && (iXPosSearch >= 0) ) iXPosSearch--;
1472    if ( iXPosSearch < 0) iXPosSearch++;
1473
1474    Int iSourcePos = iXPosSearch;
1475
1476    for( Int iXPos = iSourcePos + 1; iXPos <  iWidth; iXPos++)
1477    {
1478      for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1479      {
1480        apcOutputData[uiCurPlane][iXPos] = apcInputData[uiCurPlane][iSourcePos];
1481      }
1482    }
1483
1484    // Fill Left Gap
1485    iXPosSearch = 0;
1486    while( (pcFilledData[iXPosSearch] == REN_IS_HOLE) && (iXPosSearch < iWidth) ) iXPosSearch++;
1487    if ( iXPosSearch >= iWidth) iXPosSearch--;
1488
1489    iSourcePos = iXPosSearch;
1490
1491    for( Int iXPos = iSourcePos - 1; iXPos >= 0; iXPos--)
1492    {
1493      for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1494      {
1495        apcOutputData[uiCurPlane][iXPos] = apcInputData[uiCurPlane][iSourcePos];
1496      }
1497    }
1498
1499    // Go to next line
1500    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1501    {
1502      apcOutputData[uiCurPlane] += iOutputStride;
1503      apcInputData [uiCurPlane] += iInputStride;
1504    }
1505    pcFilledData += iFilledStride;
1506  }
1507  delete[] apcInputData;
1508  delete[] apcOutputData;
1509}
1510
1511Void TRenTop::xPostProcessImage(PelImage* pcInImage, PelImage* pcOutImage)
1512{
1513  if ( m_iPostProcMode == eRenPostProNone )
1514    return;
1515
1516  PelImage* pcTemp;
1517
1518  if (pcInImage == pcOutImage)
1519  {
1520    pcTemp = pcOutImage->create();
1521  }
1522  else
1523  {
1524    pcTemp = pcOutImage;
1525  }
1526
1527  pcTemp->assign(pcInImage);
1528
1529  switch ( m_iPostProcMode )
1530  {
1531  case eRenPostProMed:
1532    TRenFilter::lineMedian3(pcTemp);
1533    break;
1534  case eRenPostProNone:
1535    break;
1536  default:
1537    assert(0);
1538  }
1539
1540  if (pcInImage == pcOutImage)
1541  {
1542    pcOutImage->assign(pcTemp);
1543    delete pcTemp;
1544  };
1545}
1546
1547
1548Void TRenTop::xCutPlaneMargin( PelImagePlane* pcImagePlane, Pel cFill, UInt uiScale )
1549{
1550  UInt uiWidth  = pcImagePlane->getWidth();
1551  UInt uiHeight = pcImagePlane->getHeight();
1552
1553  UInt uiStride    = pcImagePlane->getStride();
1554  Pel* pcPlaneData = pcImagePlane->getPlaneData();
1555
1556  UInt uiCutLeft  =           m_auiCut[0] / uiScale;
1557  UInt uiCutRight = uiWidth - m_auiCut[1] / uiScale;
1558
1559  for(UInt uiYPos = 0; uiYPos < uiHeight; uiYPos++)
1560  {
1561    for(UInt uiXPos = 0; uiXPos < (UInt) uiWidth ; uiXPos++)
1562    {
1563      if ( ( uiXPos < uiCutLeft  )  || (  uiXPos >=  uiCutRight )  )
1564      {
1565        pcPlaneData[uiXPos ] = cFill;
1566      }
1567    }
1568    pcPlaneData += uiStride;
1569  }
1570};
1571
1572Void TRenTop::xCutMargin( PelImage* pcInputImage )
1573{
1574  if  ( ( m_auiCut[0] == 0 ) && ( m_auiCut[1] == 0 ) )
1575  {
1576    return;
1577  };
1578
1579  UInt uiCurPlane = 0;
1580  for (; uiCurPlane < pcInputImage->getNumberOfFullPlanes(); uiCurPlane++ )
1581  {
1582    xCutPlaneMargin( pcInputImage->getPlane(uiCurPlane), (Pel) 0  , 1 );
1583  }
1584
1585  for (; uiCurPlane < pcInputImage->getNumberOfPlanes(); uiCurPlane++ )
1586  {
1587    xCutPlaneMargin( pcInputImage->getPlane(uiCurPlane), (Pel) 128  , 2 );
1588  }
1589
1590};
1591
1592
1593Void TRenTop::xEnhSimilarity( PelImage* pcLeftImage, PelImage* pcRightImage, PelImage* pcFilledLeft, PelImage* pcFilledRight )
1594{
1595  if (m_iSimEnhBaseView == 0)
1596    return;
1597
1598  UInt uiNumFullPlanes = pcLeftImage->getNumberOfFullPlanes();
1599  UInt uiNumQuatPlanes = pcLeftImage->getNumberOfQuaterPlanes();
1600
1601  if (uiNumQuatPlanes > 0)
1602  {
1603    assert( pcFilledLeft ->getNumberOfPlanes() > 1);
1604    assert( pcFilledRight->getNumberOfPlanes() > 1);
1605  };
1606
1607  xEnhSimilarityPlane ( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), uiNumFullPlanes);
1608  if (uiNumQuatPlanes > 0)
1609  {
1610    xEnhSimilarityPlane ( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), uiNumQuatPlanes);
1611  }
1612}
1613
1614Void TRenTop::xEnhSimilarityPlane       ( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, UInt uiNumberOfPlanes )
1615{
1616  AOF( g_bitDepthC == g_bitDepthY ); 
1617  AOT( m_iSimEnhBaseView != 1 && m_iSimEnhBaseView != 2 );
1618  Int iWidth  = (*apcRightPlane)->getWidth ();
1619  Int iHeight = (*apcRightPlane)->getHeight();
1620
1621  Int* aiHistLeft  = new Int[ ((Int64)1 ) << g_bitDepthY ];
1622  Int* aiHistRight = new Int[ ((Int64)1 ) << g_bitDepthY ];
1623  Pel* aiConvLUT   = new Pel[ ((Int64)1 ) << g_bitDepthY ];
1624
1625  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1626  {
1627    for (Int iCurVal = 0 ; iCurVal < ( 1 << g_bitDepthY ); iCurVal++)
1628    {
1629      aiHistLeft [iCurVal] = 0;
1630      aiHistRight[iCurVal] = 0;
1631    }
1632
1633    Pel* pcFilledRightData = pcFilledRightPlane    ->getPlaneData();
1634    Pel* pcRightImageData  = (*apcRightPlane )     ->getPlaneData();
1635
1636    Pel* pcFilledLeftData  = pcFilledLeftPlane     ->getPlaneData();
1637    Pel* pcLeftImageData   = (*apcLeftPlane)       ->getPlaneData();
1638
1639 
1640
1641    for (UInt uiYPos = 0; uiYPos < iHeight; uiYPos++ )
1642    {
1643      for (UInt uiXPos = 0; uiXPos < iWidth; uiXPos++ )
1644      {
1645          if      ( pcFilledLeftData[uiXPos] == REN_IS_FILLED &&  pcFilledRightData[uiXPos] == REN_IS_FILLED )
1646          {
1647            aiHistLeft [pcLeftImageData   [uiXPos] ]++;
1648            aiHistRight[pcRightImageData  [uiXPos] ]++;
1649          }
1650      }
1651
1652
1653      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1654      pcRightImageData  += (*apcRightPlane)       ->getStride();
1655
1656      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1657      pcLeftImageData   +=  (*apcLeftPlane)       ->getStride();
1658    }
1659
1660    Int iCumSumChange  = 0;
1661    Int iCumSumBase    = 0;
1662    Int iCurBaseVal    = 0;
1663    Int iCurChangeVal  = 0;
1664
1665    Int* aiHistChange  = (m_iSimEnhBaseView == 2 ) ? aiHistLeft  : aiHistRight;
1666    Int* aiHistBase    = (m_iSimEnhBaseView == 2 ) ? aiHistRight : aiHistLeft ;
1667
1668    iCumSumChange += aiHistChange[iCurChangeVal];
1669    iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1670
1671    Int iCheckSumLeft  = 0;
1672    Int iCheckSumRight = 0;
1673
1674    for (Int iCurVal = 0 ; iCurVal < ( 1 << g_bitDepthY ); iCurVal++)
1675    {
1676      iCheckSumLeft  += aiHistLeft [iCurVal];
1677      iCheckSumRight += aiHistRight[iCurVal];
1678    }
1679
1680
1681    while( iCurChangeVal < ( 1 << g_bitDepthY ) )
1682    {
1683      if ( iCumSumBase == iCumSumChange )
1684      {
1685        aiConvLUT[iCurChangeVal] = std::min( iCurBaseVal,  ( 1 << g_bitDepthY ) - 1 );
1686        iCurBaseVal  ++;
1687        iCurChangeVal++;
1688        iCumSumChange += aiHistChange[iCurChangeVal];
1689        if (iCurBaseVal <  ( 1 << g_bitDepthY ) )
1690        {
1691          iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1692        }
1693      }
1694      else if ( iCumSumBase < iCumSumChange )
1695      {
1696        iCurBaseVal++;
1697        if (iCurBaseVal < ( 1 << g_bitDepthY ) )
1698        {
1699          iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1700        }
1701      }
1702      else if ( iCumSumBase > iCumSumChange)
1703      {
1704        aiConvLUT[iCurChangeVal] = std::min(iCurBaseVal, ( 1 << g_bitDepthY )-1);
1705        iCurChangeVal++;
1706        iCumSumChange += aiHistChange  [iCurChangeVal]  ;
1707      }
1708    }
1709
1710    Pel* pcChangeImageData   = ( ( m_iSimEnhBaseView == 2 ) ? (*apcLeftPlane) : (*apcRightPlane) )->getPlaneData();
1711    Int  iChangeImageStride  = ( ( m_iSimEnhBaseView == 2 ) ? (*apcLeftPlane) : (*apcRightPlane) )->getStride   ();
1712
1713    for (UInt uiYPos = 0; uiYPos < iHeight; uiYPos++ )
1714    {
1715      for (UInt uiXPos = 0; uiXPos < iWidth; uiXPos++ )
1716      {
1717          pcChangeImageData  [uiXPos] = aiConvLUT[ pcChangeImageData[uiXPos]];
1718      }
1719      pcChangeImageData   +=  iChangeImageStride;
1720    }
1721
1722    apcRightPlane ++;
1723    apcLeftPlane  ++;
1724
1725  }
1726
1727delete[] aiHistLeft ;
1728delete[] aiHistRight;
1729delete[] aiConvLUT  ;
1730}
1731
1732
1733Void TRenTop::xBlend( PelImage* pcLeftImage, PelImage* pcRightImage, PelImage* pcFilledLeft, PelImage* pcFilledRight, PelImage* pcLeftDepth, PelImage* pcRightDepth, PelImage* pcOutputImage )
1734{
1735  UInt uiNumFullPlanes = pcLeftImage->getNumberOfFullPlanes();
1736  UInt uiNumQuatPlanes = pcLeftImage->getNumberOfQuaterPlanes();
1737
1738  assert( uiNumFullPlanes == pcRightImage->getNumberOfFullPlanes  () && uiNumFullPlanes == pcOutputImage->getNumberOfFullPlanes    ());
1739  assert( uiNumQuatPlanes == pcRightImage->getNumberOfQuaterPlanes() && uiNumQuatPlanes == pcOutputImage->getNumberOfQuaterPlanes  ());
1740
1741  if (uiNumQuatPlanes > 0)
1742  {
1743    assert( pcLeftDepth ->getNumberOfPlanes() > 1 || pcFilledLeft ->getNumberOfPlanes() > 1);
1744    assert( pcRightDepth->getNumberOfPlanes() > 1 || pcFilledRight->getNumberOfPlanes() > 1);
1745  };
1746
1747  switch (m_iBlendMode)
1748  {
1749  case eRenBlendAverg:
1750  case eRenBlendDepthFirst:
1751    xBlendPlanesAvg( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), pcLeftDepth->getPlane(0), pcRightDepth->getPlane(0), pcOutputImage->getPlanes(), uiNumFullPlanes);
1752    if (uiNumQuatPlanes > 0)
1753    {
1754      xBlendPlanesAvg( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), pcLeftDepth->getPlane(1), pcRightDepth->getPlane(1), pcOutputImage->getPlanes()+uiNumFullPlanes, uiNumQuatPlanes);
1755    }
1756    break;
1757  case eRenBlendLeft:
1758  case eRenBlendRight:
1759    xBlendPlanesOneView( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), pcLeftDepth->getPlane(0), pcRightDepth->getPlane(0), pcOutputImage->getPlanes(), uiNumFullPlanes);
1760    if (uiNumQuatPlanes > 0)
1761    {
1762      xBlendPlanesOneView( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), pcLeftDepth->getPlane(1), pcRightDepth->getPlane(1), pcOutputImage->getPlanes()+uiNumFullPlanes, uiNumQuatPlanes);
1763    }
1764    break;
1765  }
1766}
1767
1768Void TRenTop::xBlendPlanesOneView( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, PelImagePlane* pcLeftDepthPlane, PelImagePlane* pcRightDepthPlane, PelImagePlane** apcOutputImagePlane, UInt uiNumberOfPlanes )
1769{
1770  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1771  {
1772    Pel* pcFilledRightData = pcFilledRightPlane    ->getPlaneData();
1773    Pel* pcRightImageData  = (*apcRightPlane )     ->getPlaneData();
1774    Pel* pcRightDepthData  = pcRightDepthPlane     ->getPlaneData();
1775
1776    Pel* pcFilledLeftData  = pcFilledLeftPlane     ->getPlaneData();
1777    Pel* pcLeftImageData   = (*apcLeftPlane)       ->getPlaneData();
1778    Pel* pcLeftDepthData   = pcLeftDepthPlane      ->getPlaneData();
1779    Pel* pcOutputData      = (*apcOutputImagePlane)->getPlaneData();
1780
1781    for (UInt uiYPos = 0; uiYPos < (*apcOutputImagePlane)->getHeight(); uiYPos++ )
1782    {
1783      for (UInt uiXPos = 0; uiXPos < (*apcOutputImagePlane)->getWidth(); uiXPos++ )
1784      {
1785        if      (m_iBlendMode == eRenBlendLeft  )
1786        {
1787          if      ( pcFilledLeftData[uiXPos] == REN_IS_FILLED ||  pcFilledRightData[uiXPos] == REN_IS_HOLE )
1788          {
1789            pcOutputData[uiXPos] = pcLeftImageData[uiXPos];
1790          }
1791          else if ( pcFilledLeftData[uiXPos] == REN_IS_HOLE )
1792          {
1793            pcOutputData[uiXPos] = pcRightImageData[uiXPos];
1794          }
1795          else
1796          {
1797            pcOutputData[uiXPos] = pcRightImageData[uiXPos] +  (Pel) (  ( (Int) ( pcLeftImageData[uiXPos] - pcRightImageData[uiXPos] ) * pcFilledLeftData[uiXPos] + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1798          }
1799        }
1800        else if ( m_iBlendMode == eRenBlendRight )
1801        {
1802          if      ( pcFilledRightData[uiXPos] == REN_IS_FILLED || pcFilledLeftData[uiXPos] == REN_IS_HOLE )
1803          {
1804            pcOutputData[uiXPos] = pcRightImageData[uiXPos];
1805          }
1806          else if ( pcFilledRightData[uiXPos] == REN_IS_HOLE )
1807          {
1808            pcOutputData[uiXPos] = pcLeftImageData[uiXPos];
1809          }
1810          else
1811          {
1812            pcOutputData[uiXPos] = pcLeftImageData[uiXPos] +  (Pel) (  ( (Int) ( pcRightImageData[uiXPos] - pcLeftImageData[uiXPos] ) * pcFilledRightData[uiXPos] + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1813          }
1814        }
1815        else
1816        {
1817          AOT(true);
1818        }
1819      }
1820
1821      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1822      pcRightImageData  += (*apcRightPlane)       ->getStride();
1823      pcRightDepthData  +=    pcRightDepthPlane   ->getStride();
1824
1825      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1826      pcLeftImageData   +=  (*apcLeftPlane)       ->getStride();
1827      pcLeftDepthData   +=    pcLeftDepthPlane    ->getStride();
1828      pcOutputData      +=  (*apcOutputImagePlane)->getStride();
1829    }
1830
1831    apcRightPlane ++;
1832    apcLeftPlane  ++;
1833    apcOutputImagePlane++;
1834  }
1835}
1836
1837Void TRenTop::xBlendPlanesAvg( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, PelImagePlane* pcLeftDepthPlane, PelImagePlane* pcRightDepthPlane, PelImagePlane** apcOutputImagePlane, UInt uiNumberOfPlanes )
1838{
1839  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1840  {
1841    Pel* pcFilledRightData = pcFilledRightPlane   ->getPlaneData();
1842    Pel* pcRightVideoData  = (*apcRightPlane )    ->getPlaneData();
1843    Pel* pcRightDepthData  = pcRightDepthPlane    ->getPlaneData();
1844
1845    Pel* pcFilledLeftData  = pcFilledLeftPlane    ->getPlaneData();
1846    Pel* pcLeftVideoData   = (*apcLeftPlane)      ->getPlaneData();
1847    Pel* pcLeftDepthData   = pcLeftDepthPlane     ->getPlaneData();
1848
1849    Pel* pcOutputData      = (*apcOutputImagePlane)->getPlaneData();
1850
1851    for (UInt uiYPos = 0; uiYPos < (*apcOutputImagePlane)->getHeight(); uiYPos++ )
1852    {
1853      for (UInt uiXPos = 0; uiXPos < (*apcOutputImagePlane)->getWidth(); uiXPos++ )
1854      {
1855        if      (  (pcFilledRightData[uiXPos] != REN_IS_HOLE ) && ( pcFilledLeftData[uiXPos] != REN_IS_HOLE) )
1856        {
1857          Int iDepthDifference  = m_piInvZLUTLeft[RemoveBitIncrement(pcLeftDepthData[uiXPos])] - m_piInvZLUTRight[RemoveBitIncrement(pcRightDepthData[uiXPos])];
1858
1859          if ( abs ( iDepthDifference ) <= m_iBlendZThres )
1860          {
1861            if      ((pcFilledRightData[uiXPos] == REN_IS_FILLED) && ( pcFilledLeftData[uiXPos] != REN_IS_FILLED))
1862            {
1863              pcOutputData[uiXPos] = pcRightVideoData[uiXPos] +  (Pel) (  ( (Int) ( pcLeftVideoData[uiXPos] - pcRightVideoData[uiXPos] ) * (pcFilledLeftData[uiXPos]) + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1864            }
1865            else if ((pcFilledRightData[uiXPos] != REN_IS_FILLED) && ( pcFilledLeftData[uiXPos] == REN_IS_FILLED))
1866            {
1867              pcOutputData[uiXPos] = pcLeftVideoData[uiXPos]  +  (Pel) (  ( (Int) ( pcRightVideoData[uiXPos] - pcLeftVideoData[uiXPos] ) * (pcFilledRightData[uiXPos]) + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1868            }
1869            else
1870            {
1871              pcOutputData[uiXPos] = pcLeftVideoData[uiXPos]  +  (Pel) (  ( (Int) ( pcRightVideoData[uiXPos] - pcLeftVideoData[uiXPos] ) * m_iBlendDistWeight               + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1872            }
1873
1874          }
1875          else if ( iDepthDifference < 0 )
1876          {
1877            pcOutputData[uiXPos] = pcRightVideoData[uiXPos];
1878          }
1879          else
1880          {
1881            pcOutputData[uiXPos] = pcLeftVideoData[uiXPos];
1882          }
1883        }
1884        else if ( (pcFilledRightData[uiXPos] == REN_IS_HOLE) && (pcFilledLeftData[uiXPos] == REN_IS_HOLE))
1885        {
1886          pcOutputData[uiXPos] = m_piInvZLUTLeft[RemoveBitIncrement( pcLeftDepthData[uiXPos])]  < m_piInvZLUTRight[RemoveBitIncrement(pcRightDepthData[uiXPos])] ? pcLeftVideoData[uiXPos] : pcRightVideoData[uiXPos];
1887        }
1888        else
1889        {
1890          pcOutputData[uiXPos] =  (pcFilledLeftData[uiXPos] == REN_IS_HOLE) ? pcRightVideoData[uiXPos] : pcLeftVideoData[uiXPos];
1891        }
1892      }
1893
1894      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1895      pcRightVideoData  += (*apcRightPlane)      ->getStride();
1896      pcRightDepthData  +=    pcRightDepthPlane   ->getStride();
1897
1898      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1899      pcLeftVideoData   +=  (*apcLeftPlane)       ->getStride();
1900      pcLeftDepthData   +=    pcLeftDepthPlane    ->getStride();
1901      pcOutputData      +=  (*apcOutputImagePlane)->getStride();
1902    };
1903
1904    apcRightPlane ++;
1905    apcLeftPlane  ++;
1906    apcOutputImagePlane++;
1907  }
1908}
1909
1910// Temporal Filter from Zhejiang University: (a little different from m16041: Temporal Improvement Method in View Synthesis)
1911Void TRenTop::temporalFilterVSRS( TComPicYuv* pcPicYuvVideoCur, TComPicYuv* pcPicYuvDepthCur, TComPicYuv* pcPicYuvVideoLast, TComPicYuv* pcPicYuvDepthLast, Bool bFirstFrame )
1912{
1913  AOF( g_bitDepthY == g_bitDepthC ); 
1914  Int iSADThres  = 100 ;  //threshold of sad in 4*4 block motion detection
1915
1916  Int iWidth  = m_auiInputResolution[0];
1917  Int iHeight = m_auiInputResolution[1];
1918
1919  //internal variables
1920  Int* piFlagMoving =  m_aiBlkMoving + 2;
1921
1922  Int iVideoCurStride     = pcPicYuvVideoCur ->getStride();
1923  Int iVideoLastStride    = pcPicYuvVideoLast->getStride();
1924  Int iDepthCurStride     = pcPicYuvDepthCur ->getStride();
1925  Int iDepthLastStride    = pcPicYuvDepthLast->getStride();
1926
1927  Pel* pcVideoCurData     = pcPicYuvVideoCur ->getLumaAddr();
1928  Pel* pcVideoLastData    = pcPicYuvVideoLast->getLumaAddr();
1929  Pel* pcDepthCurData     = pcPicYuvDepthCur ->getLumaAddr();
1930  Pel* pcDepthLastData    = pcPicYuvDepthLast->getLumaAddr();
1931
1932  Pel* pcVideoCurDataFrm  = pcVideoCurData ;
1933  Pel* pcVideoLastDataFrm = pcVideoLastData;
1934  Pel* pcDepthCurDataFrm  = pcDepthCurData ;
1935  Pel* pcDepthLastDataFrm = pcDepthLastData;
1936
1937
1938  if( !bFirstFrame ) // first frame need not the weighting, but need to prepare the data
1939  {
1940    for ( Int iPosY = 0; iPosY < (iHeight >> 2); iPosY++)
1941    {
1942      //motion detection by SAD
1943      for ( Int iPosX = 0; iPosX < (iWidth >> 2);  iPosX++)
1944      {
1945        Int iSAD = 0;
1946
1947        Pel* pcVideoCurDataBlk  = pcVideoCurDataFrm  + (iPosX << 2);
1948        Pel* pcVideoLastDataBlk = pcVideoLastDataFrm + (iPosX << 2);
1949
1950        //GT: Check difference of block compared to last frame
1951        for( Int iCurPosY = 0; iCurPosY < 4; iCurPosY++)
1952        {
1953          for( Int iCurPosX = 0; iCurPosX < 4; iCurPosX++)
1954          {
1955            iSAD += abs( pcVideoLastDataBlk[iCurPosX] - pcVideoCurDataBlk[iCurPosX] );   //SAD
1956          }
1957          pcVideoLastDataBlk += iVideoLastStride;
1958          pcVideoCurDataBlk  += iVideoCurStride;
1959        }
1960
1961        piFlagMoving[iPosX] = ( iSAD < iSADThres ) ? 0 : 1;
1962      }
1963
1964      //temporal weighting according to motion detection result -- do a line
1965      for ( Int iPosX = 0; iPosX < (iWidth >> 2);  iPosX++)
1966      {
1967        //5 block
1968       Int iSumMoving = piFlagMoving[iPosX-2] + piFlagMoving[iPosX-1] + piFlagMoving[iPosX]   + piFlagMoving[iPosX+1] + piFlagMoving[iPosX+2];
1969
1970        if( iSumMoving == 0 ) // if not moving
1971        {
1972          Pel* pcDepthCurDataBlk  = pcDepthCurDataFrm  + (iPosX << 2);
1973          Pel* pcDepthLastDataBlk = pcDepthLastDataFrm + (iPosX << 2);
1974
1975          for( Int iCurPosY = 0; iCurPosY < 4; iCurPosY++)
1976          {
1977            for( Int iCurPosX = 0; iCurPosX < 4; iCurPosX++)
1978            { //Weight: 0.75
1979              Int iFilt = (( (pcDepthLastDataBlk[iCurPosX] << 1 ) + pcDepthLastDataBlk[iCurPosX] + pcDepthCurDataBlk[iCurPosX] + 2 ) >> 2 );
1980              assert( (iFilt >= 0) && (iFilt <  ( 1 << g_bitDepthY ) ) );
1981              pcDepthCurDataBlk[iCurPosX] = pcDepthLastDataBlk[iCurPosX];
1982              pcDepthCurDataBlk[iCurPosX] = iFilt;
1983            }
1984
1985            pcDepthCurDataBlk  += iDepthCurStride;
1986            pcDepthLastDataBlk += iDepthLastStride;
1987          }
1988        }
1989      }
1990
1991      pcDepthCurDataFrm  += ( iDepthCurStride  << 2);
1992      pcDepthLastDataFrm += ( iDepthLastStride << 2);
1993      pcVideoCurDataFrm  += ( iVideoCurStride  << 2);
1994      pcVideoLastDataFrm += ( iVideoLastStride << 2);
1995    }
1996  }
1997  pcPicYuvVideoCur->copyToPic( pcPicYuvVideoLast );
1998  pcPicYuvDepthCur->copyToPic( pcPicYuvDepthLast );
1999}
2000
2001TRenTop::TRenTop()
2002{
2003  m_auiInputResolution[0] = 0;
2004  m_auiInputResolution[1] = 0;
2005
2006  // Sub Pel Rendering
2007  m_iLog2SamplingFactor = 0;
2008
2009  // ColorPlaneHandling
2010  m_bUVUp = true;
2011
2012
2013  //PreProcessing
2014  m_iPreProcMode         = eRenPreProNone;
2015  m_iPreFilterSize = 2;
2016
2017  // Interpolation
2018  m_iInterpolationMode   = eRenIntFullPel;
2019
2020  // Sim Enhancement
2021  m_iSimEnhBaseView      = 0;
2022
2023  // Blending
2024  m_iBlendMode           = eRenBlendAverg;
2025  m_iBlendZThresPerc     = -1;
2026  m_bBlendUseDistWeight  = false;
2027  m_iBlendHoleMargin     = -1;
2028
2029  m_iBlendZThres         = -1;
2030  m_iBlendDistWeight     = -1;
2031
2032  // Hole Filling
2033  m_iHoleFillingMode     = eRenHFLWBackExt;
2034  m_bInstantHoleFilling  = false;
2035
2036  // PostProcessing
2037  m_iPostProcMode        = eRenPostProNone;
2038
2039  // Cut
2040  m_auiCut[0] = 0;
2041  m_auiCut[1] = 0;
2042
2043  // Data
2044  m_uiSampledWidth = -1;
2045
2046  // LUTs
2047  m_ppdShiftLUTLeft  = 0;
2048  m_ppdShiftLUTRight = 0;
2049
2050  m_ppdShiftLUTRightMirror    = new Double*[2];
2051  m_ppdShiftLUTRightMirror[0] = new Double [257];
2052  m_ppdShiftLUTRightMirror[1] = new Double [257];
2053
2054  m_adShiftLUTCur    = 0;
2055
2056  m_ppiShiftLUTLeft  = 0;
2057  m_ppiShiftLUTRight = 0;
2058  m_ppiShiftLUTRightMirror    = new Int*[2];
2059  m_ppiShiftLUTRightMirror[0] = new Int[257];
2060  m_ppiShiftLUTRightMirror[1] = new Int[257];
2061
2062  m_aiShiftLUTCur    = 0;
2063  m_piInvZLUTLeft  = new Int[257];
2064  m_piInvZLUTRight = new Int[257];
2065
2066  // Buffers
2067  m_pcLeftInputImage   = 0;
2068  m_pcLeftInputDepth   = 0;
2069  m_pcLeftOutputImage  = 0;
2070  m_pcLeftOutputDepth  = 0;
2071  m_pcLeftFilled       = 0;
2072
2073  m_pcRightInputImage  = 0;
2074  m_pcRightInputDepth  = 0;
2075  m_pcRightOutputImage = 0;
2076  m_pcRightOutputDepth = 0;
2077  m_pcRightFilled      = 0;
2078
2079  m_pcOutputImage      = 0;
2080  m_pcOutputDepth      = 0;
2081
2082  //Extrapolation
2083  m_pcInputImage       = 0;
2084  m_pcInputDepth       = 0;
2085  m_pcFilled           = 0;
2086
2087  // SubPel
2088  m_aaiSubPelShift     = 0;
2089
2090  // Temp
2091  m_pcTempImage        = 0;
2092
2093  //Temporal Filter
2094  m_aiBlkMoving        = 0;
2095}
2096
2097
2098Void TRenTop::init(UInt uiImageWidth,
2099                   UInt uiImageHeight,
2100                   Bool  bExtrapolate,
2101                   UInt uiLog2SamplingFactor,
2102                   Int   iShiftLUTPrec,
2103                   Bool  bUVUp,
2104                   Int   iPreProcMode,
2105                   Int   iPreFilterKernelSize,
2106                   Int   iBlendMode,
2107                   Int   iBlendZThresPerc,
2108                   Bool  bBlendUseDistWeight,
2109                   Int   iBlendHoleMargin,
2110                   Int   iInterpolationMode,
2111                   Int   iHoleFillingMode,
2112                   Int   iPostProcMode,
2113                   Int   iUsedPelMapMarExt
2114                   )
2115
2116{
2117  // Shift LUT Prec
2118  m_iRelShiftLUTPrec = iShiftLUTPrec - (Int) uiLog2SamplingFactor;
2119
2120  // Sub Pel Rendering
2121  m_iLog2SamplingFactor = uiLog2SamplingFactor;
2122
2123  // Extrapolation ?
2124  m_bExtrapolate = bExtrapolate;
2125
2126  // ColorPlaneHandling
2127  m_bUVUp = bUVUp;
2128
2129  //PreProcessing
2130  m_iPreProcMode = iPreProcMode;
2131  m_iPreFilterSize = iPreFilterKernelSize;
2132
2133  // Interpolation
2134  m_iInterpolationMode = iInterpolationMode;
2135
2136  //Blending
2137  m_iBlendMode          = iBlendMode;
2138  m_iBlendZThresPerc    = iBlendZThresPerc;
2139  m_bBlendUseDistWeight = bBlendUseDistWeight;
2140  m_iBlendHoleMargin    = iBlendHoleMargin;
2141
2142  // Hole Filling
2143  m_iHoleFillingMode = iHoleFillingMode;
2144
2145  m_bInstantHoleFilling   = (m_iInterpolationMode == eRenInt8Tap ) && (m_iHoleFillingMode != 0 );
2146
2147  // PostProcessing
2148  m_iPostProcMode    = iPostProcMode;
2149
2150  // Used pel map
2151  m_iUsedPelMapMarExt     = iUsedPelMapMarExt;
2152
2153  // Cut
2154  m_auiCut[0] = 0;
2155  m_auiCut[1] = 0;
2156
2157  m_auiInputResolution[0] = uiImageWidth;
2158  m_auiInputResolution[1] = uiImageHeight;
2159
2160  if ( m_bExtrapolate )
2161  {
2162    PelImage*    pcDump        = 0;
2163    xGetDataPointers( m_pcInputImage, m_pcOutputImage, m_pcInputDepth, pcDump, m_pcFilled, false );
2164  }
2165  else
2166  {
2167    xGetDataPointers(m_pcLeftInputImage,  m_pcLeftOutputImage,  m_pcLeftInputDepth,  m_pcLeftOutputDepth,  m_pcLeftFilled,  true);
2168    xGetDataPointers(m_pcRightInputImage, m_pcRightOutputImage, m_pcRightInputDepth, m_pcRightOutputDepth, m_pcRightFilled, true);
2169    xGetDataPointerOutputImage(m_pcOutputImage, m_pcOutputDepth );
2170  }
2171
2172  m_pcTempImage = new PelImage( m_auiInputResolution[0],m_auiInputResolution[1],1,2);
2173
2174  // SubPelShiftLUT
2175  if (iInterpolationMode == eRenInt8Tap)
2176  {
2177    // SubPel Shift LUT
2178    Int iNumEntries = (1 << ( m_iRelShiftLUTPrec + 1) ) + 1 ;
2179    m_aaiSubPelShift = new Int*[ iNumEntries ];
2180    for (UInt uiEntry = 0; uiEntry < iNumEntries; uiEntry++)
2181    {
2182      m_aaiSubPelShift[uiEntry] = new Int[ iNumEntries ];
2183    }
2184
2185    TRenFilter::setSubPelShiftLUT(m_iRelShiftLUTPrec, m_aaiSubPelShift, -1);
2186  }
2187
2188  // Zheijang temporal filter
2189  m_aiBlkMoving    = new Int[ ( m_auiInputResolution[0] >> 2 ) + 4 ];
2190  m_aiBlkMoving[0] = 0;
2191  m_aiBlkMoving[1] = 0;
2192  m_aiBlkMoving[ ( m_auiInputResolution[0] >> 2 ) + 2 ] = 0;
2193  m_aiBlkMoving[ ( m_auiInputResolution[0] >> 2 ) + 3 ] = 0;
2194}
2195
2196
2197TRenTop::~TRenTop()
2198{
2199  if ( m_ppdShiftLUTRightMirror != NULL )
2200  {
2201    delete[] m_ppdShiftLUTRightMirror[0];
2202    delete[] m_ppdShiftLUTRightMirror[1];
2203    delete[] m_ppdShiftLUTRightMirror;
2204  };
2205
2206  if ( m_ppiShiftLUTRightMirror != NULL )
2207  {
2208    delete[] m_ppiShiftLUTRightMirror[0];
2209    delete[] m_ppiShiftLUTRightMirror[1];
2210    delete[] m_ppiShiftLUTRightMirror;
2211  };
2212
2213  if (m_piInvZLUTLeft      != NULL ) delete[] m_piInvZLUTLeft   ;
2214  if (m_piInvZLUTLeft      != NULL ) delete[] m_piInvZLUTRight  ;
2215
2216  if (m_pcLeftInputImage   != NULL ) delete m_pcLeftInputImage  ;
2217  if (m_pcLeftInputDepth   != NULL ) delete m_pcLeftInputDepth  ;
2218  if (m_pcLeftOutputImage  != NULL ) delete m_pcLeftOutputImage ;
2219  if (m_pcLeftOutputDepth  != NULL ) delete m_pcLeftOutputDepth ;
2220  if (m_pcLeftFilled       != NULL ) delete m_pcLeftFilled      ;
2221
2222  if (m_pcRightInputImage  != NULL ) delete m_pcRightInputImage ;
2223  if (m_pcRightInputDepth  != NULL ) delete m_pcRightInputDepth ;
2224  if (m_pcRightOutputImage != NULL ) delete m_pcRightOutputImage;
2225  if (m_pcRightOutputDepth != NULL ) delete m_pcRightOutputDepth;
2226  if (m_pcRightFilled      != NULL ) delete m_pcRightFilled     ;
2227
2228  if (m_pcOutputImage      != NULL ) delete m_pcOutputImage     ;
2229  if (m_pcOutputDepth      != NULL ) delete m_pcOutputDepth     ;
2230
2231  if (m_pcInputImage       != NULL ) delete m_pcInputImage      ;
2232  if (m_pcInputDepth       != NULL ) delete m_pcInputDepth      ;
2233  if (m_pcFilled           != NULL ) delete m_pcFilled          ;
2234
2235  if (m_pcTempImage        != NULL ) delete m_pcTempImage       ;
2236
2237  // SubPel LUT
2238  if ( m_aaiSubPelShift != NULL)
2239  {
2240    Int iNumEntries = (1 << ( m_iRelShiftLUTPrec + 1) ) + 1;
2241    for (UInt uiEntry = 0; uiEntry < iNumEntries; uiEntry++)
2242    {
2243      delete[] m_aaiSubPelShift[uiEntry];
2244    }
2245    delete[] m_aaiSubPelShift;
2246  }
2247
2248  // Zheijang temporal filter
2249  if(m_aiBlkMoving         != NULL ) delete[] m_aiBlkMoving;
2250}
2251#endif // H_3D
2252
Note: See TracBrowser for help on using the repository browser.