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

Last change on this file since 1313 was 1313, checked in by tech, 9 years ago

Merged 14.1-update-dev1@1312.

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