source: 3DVCSoftware/branches/HTM-DEV-0.2-dev/source/Lib/TLibRenderer/TRenTop.cpp @ 438

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

Integrated 3D encoder control, camera parameters, renderer and MV fixes.

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