source: 3DVCSoftware/branches/HTM-13.1-dev2-HHI/source/Lib/TLibRenderer/TRenTop.cpp @ 1161

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

Merged 8.1-Cleanup@654

  • Property svn:eol-style set to native
File size: 79.2 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2011, ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35#include "TRenImage.h"
36#include "TRenTop.h"
37
38#include "TRenFilter.h"
39#include <iostream>
40#include <math.h>
41#include "../TLibCommon/CommonDef.h"
42#if H_3D
43
44
45Void TRenTop::xGetDataPointers( PelImage*& rpcInputImage, PelImage*& rpcOutputImage, PelImage*& rpcInputDepth, PelImage*& rpcOutputDepth, PelImage*& rpcFilled, Bool bRenderDepth )
46{
47  UInt uiWidth = m_auiInputResolution[0] << m_iLog2SamplingFactor;
48
49  UInt uiSubPelWidth  = uiWidth;
50
51  if ( m_iInterpolationMode == eRenInt8Tap )
52  {
53    uiSubPelWidth <<= m_iRelShiftLUTPrec;
54  }
55
56  UInt uiHeight = m_auiInputResolution[1];
57
58  if ( m_bUVUp )
59  {
60    rpcInputDepth  = new PelImage(uiSubPelWidth, uiHeight,1,0);
61    rpcInputImage  = new PelImage(uiSubPelWidth, uiHeight,3,0);
62    rpcOutputImage = new PelImage(uiWidth,        uiHeight,3,0);
63    rpcOutputDepth = bRenderDepth  ? new PelImage(uiWidth, uiHeight,1,0) : 0;
64    rpcFilled      = new PelImage(uiWidth, uiHeight,1,0);
65  }
66  else
67  {
68    rpcInputDepth  = new PelImage(uiSubPelWidth, uiHeight,1,1);
69    rpcInputImage  = new PelImage(uiSubPelWidth, uiHeight,1,2);
70    rpcOutputImage = new PelImage(uiWidth,        uiHeight,1,2);
71    rpcOutputDepth = bRenderDepth ? new PelImage(uiWidth, uiHeight,1,1) : 0;
72    rpcFilled      = new PelImage(uiWidth,        uiHeight,1,1);
73  }
74
75}
76
77Void TRenTop::xGetDataPointerOutputImage( PelImage*& rpcOutputImage, PelImage*& rpcOutputDepth )
78{
79
80  UInt uiWidth  = m_auiInputResolution[0] << m_iLog2SamplingFactor;
81  UInt uiHeight = m_auiInputResolution[1];
82
83  if ( m_bUVUp )
84  {
85    rpcOutputImage = new PelImage(uiWidth, uiHeight,3,0);
86    rpcOutputDepth = (m_iBlendMode == eRenBlendDepthFirst ) ? new PelImage(uiWidth, uiHeight,1,0) : NULL;
87  }
88  else
89  {
90    rpcOutputImage = new PelImage(uiWidth, uiHeight,1,2);
91    rpcOutputDepth = (m_iBlendMode == eRenBlendDepthFirst ) ? new PelImage(uiWidth, uiHeight,1,1) : NULL;
92  }
93}
94
95Void TRenTop::xConvertInputVideo( PelImage* pcOrgInputImage, PelImage* pcConvInputImage)
96{
97  TRenImagePlane<Pel>*  pcOrgPlane ;
98  TRenImagePlane<Pel>*  pcConvPlane;
99
100  Int iLog2SamplingFactor = m_iLog2SamplingFactor;
101
102  if ( m_iInterpolationMode == eRenInt8Tap)
103  {
104    iLog2SamplingFactor += m_iRelShiftLUTPrec;
105  }
106
107  AOT( iLog2SamplingFactor > 2);
108
109  for (UInt uiPlane = 0; uiPlane < 3; uiPlane++)
110  {
111    pcOrgPlane  = pcOrgInputImage ->getPlane(uiPlane);
112    pcConvPlane = pcConvInputImage->getPlane(uiPlane);
113
114    if (uiPlane == 0)
115    {
116      TRenFilter::sampleHorUp    ( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
117    }
118    else
119    {
120      if ( m_bUVUp )
121      {
122        TRenFilter::sampleCUpHorUp( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
123      }
124      else
125      {
126        TRenFilter::sampleCHorUp   ( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
127      }
128    }
129  }
130}
131
132Void TRenTop::xConvertInputDepth( PelImage* pcOrgInputImage, PelImage* pcConvInputImage)
133{
134  PelImagePlane*  pcOrgPlane ;
135  PelImagePlane*  pcConvPlane;
136
137  // Full Plane
138  pcOrgPlane  = pcOrgInputImage ->getPlane(0);
139  pcConvPlane = pcConvInputImage->getPlane(0);
140
141  Int iLog2SamplingFactor = m_iLog2SamplingFactor;
142
143  if ( m_iInterpolationMode == eRenInt8Tap)
144  {
145    iLog2SamplingFactor += m_iRelShiftLUTPrec;
146  }
147  AOT( iLog2SamplingFactor > 2);
148
149  TRenFilter::sampleHorUp(iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
150
151  if ( !m_bUVUp ) //GT: depth down
152  {
153    // Quarter Plane
154    PelImagePlane* pcTempPlane = new PelImagePlane(pcOrgInputImage->getPlane(0)->getWidth(), ( pcOrgInputImage->getPlane(0)->getHeight() >> 1), REN_LUMA_MARGIN );
155
156    TRenFilter::sampleVerDown2Tap13(pcOrgInputImage->getPlane(0), pcTempPlane, PICYUV_PAD);
157    pcConvPlane = pcConvInputImage->getPlane(1);
158
159    if ( iLog2SamplingFactor == 0 )
160    {
161      TRenFilter::sampleHorDown2Tap13(pcTempPlane, pcConvPlane, 0 );
162    }
163    else
164    {
165      TRenFilter::sampleHorUp    ( iLog2SamplingFactor - 1, pcTempPlane->getPlaneData(), pcTempPlane->getStride(), pcTempPlane->getWidth(), pcTempPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
166    }
167    delete pcTempPlane;
168  }
169}
170
171Void TRenTop::xConvertInputData( PelImage* pcOrgInputImage, PelImage* pcOrgInputDepth, PelImage* pcConvInputImage, PelImage* pcConvInputDepth, Bool bMirror )
172{
173  //ToDo: remove unnecessary copying
174  if ( bMirror )
175  {
176    m_pcTempImage->assign( pcOrgInputImage );
177    TRenFilter::mirrorHor( m_pcTempImage );
178    m_pcTempImage->extendMargin();
179    xConvertInputVideo(    m_pcTempImage, pcConvInputImage );
180
181    m_pcTempImage->getPlane(0)->assign( pcOrgInputDepth->getPlane(0) );
182    TRenFilter::mirrorHor( m_pcTempImage->getPlane(0) );
183    m_pcTempImage->getPlane(0)->extendMargin();
184    xConvertInputDepth( m_pcTempImage, pcConvInputDepth );
185  }
186  else
187  {
188    m_pcTempImage->assign( pcOrgInputImage );
189    m_pcTempImage->extendMargin();
190    xConvertInputVideo( m_pcTempImage, pcConvInputImage );
191
192    m_pcTempImage->getPlane(0)->assign( pcOrgInputDepth->getPlane(0) );
193    m_pcTempImage->getPlane(0)->extendMargin();
194    xConvertInputDepth( m_pcTempImage, pcConvInputDepth );
195  }
196}
197
198Void TRenTop::xConvertOutputData( PelImage* pcOrgOutputImage, PelImage* pcConvOutputImage, Bool bMirror )
199{
200  Int iLog2SamplingFactor = m_iLog2SamplingFactor;
201
202  for ( UInt uiPlane = 0; uiPlane < 3; uiPlane++)
203  {
204    PelImagePlane* pcOrgPlane  = pcOrgOutputImage ->getPlane(uiPlane);
205    PelImagePlane* pcConvPlane = pcConvOutputImage->getPlane(uiPlane);
206
207    pcOrgPlane->extendMargin();
208
209    if ( uiPlane == 0 )
210    {
211      TRenFilter::sampleHorDown( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
212    }
213    else
214    {
215      if ( m_bUVUp )
216      {
217        TRenFilter::sampleCDownHorDown( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
218      }
219      else
220      {
221        TRenFilter::sampleCHorDown    ( iLog2SamplingFactor, pcOrgPlane->getPlaneData(), pcOrgPlane->getStride(), pcOrgPlane->getWidth(), pcOrgPlane->getHeight(), pcConvPlane->getPlaneData(), pcConvPlane->getStride());
222      }
223    }
224  }
225
226  if ( bMirror )
227  {
228    TRenFilter::mirrorHor( pcConvOutputImage );
229  }
230
231}
232
233Void TRenTop::setShiftLUTs( Double** ppdShiftLUTLeft, Int** ppiShiftLUTLeft, Int** ppiBaseShiftLUTLeft, Double** ppdShiftLUTRight, Int** ppiShiftLUTRight, Int** ppiBaseShiftLUTRight,  Int iRelDistToLeft )
234{
235  m_ppdShiftLUTLeft  = ppdShiftLUTLeft;
236  m_ppdShiftLUTRight = ppdShiftLUTRight;
237
238  m_ppiShiftLUTLeft  = ppiShiftLUTLeft;
239  m_ppiShiftLUTRight = ppiShiftLUTRight;
240
241  if (  m_ppdShiftLUTRight != NULL && m_ppiShiftLUTRight != NULL )
242  {
243    for( UInt uiPlane = 0; uiPlane < 2; uiPlane++)
244    {
245      for (UInt uiDepthValue = 0; uiDepthValue <= 256; uiDepthValue++)
246      {
247        m_ppdShiftLUTRightMirror[uiPlane][uiDepthValue] = - m_ppdShiftLUTRight[uiPlane][uiDepthValue];
248        m_ppiShiftLUTRightMirror[uiPlane][uiDepthValue] = - m_ppiShiftLUTRight[uiPlane][uiDepthValue];
249      }
250    }
251  }
252
253  if ( !m_bExtrapolate )
254  {
255    TRenFilter::setupZLUT( m_bBlendUseDistWeight, m_iBlendZThresPerc, iRelDistToLeft, ppiBaseShiftLUTLeft, ppiBaseShiftLUTRight, m_iBlendZThres, m_iBlendDistWeight, m_piInvZLUTLeft, m_piInvZLUTRight);
256  }
257}
258
259Void TRenTop::extrapolateView( TComPicYuv* pcPicYuvVideo, TComPicYuv* pcPicYuvDepth, TComPicYuv* pcPicYuvSynthOut, Bool bRenderFromLeft )
260{
261  AOF( m_bExtrapolate );
262  AOF( bRenderFromLeft ? m_ppiShiftLUTLeft || m_ppdShiftLUTLeft : m_ppiShiftLUTRight || m_ppdShiftLUTRight );
263  AOF( m_auiInputResolution[0] == pcPicYuvVideo->getWidth ());
264  AOF( m_auiInputResolution[1] == pcPicYuvVideo->getHeight());
265
266  PelImage cInputImage ( pcPicYuvVideo    );
267  PelImage cInputDepth ( pcPicYuvDepth    , true);
268  PelImage cOutputImage( pcPicYuvSynthOut );
269
270  m_pcOutputImage->init();
271  m_pcFilled     ->assign(REN_IS_HOLE);
272
273  xPreProcessDepth ( &cInputDepth,  &cInputDepth);
274  xConvertInputData( &cInputImage, &cInputDepth, m_pcInputImage, m_pcInputDepth, !bRenderFromLeft );
275  xShiftPixels(m_pcInputImage, m_pcInputDepth, m_pcOutputImage, m_pcFilled, bRenderFromLeft);
276  xRemBoundaryNoise ( m_pcOutputImage, m_pcFilled, m_pcOutputImage, bRenderFromLeft); // Erode
277  xFillHoles        ( m_pcOutputImage, m_pcFilled, m_pcOutputImage, bRenderFromLeft);
278  xConvertOutputData( m_pcOutputImage, &cOutputImage, !bRenderFromLeft );
279  xPostProcessImage (&cOutputImage, &cOutputImage);
280  xCutMargin        ( &cOutputImage );
281};
282
283Void TRenTop::getUsedSamplesMap( TComPicYuv* pcPicYuvDepth, TComPicYuv* pcUsedSampleMap, Bool bRenderFromLeft )
284{
285  AOF( bRenderFromLeft ? m_ppiShiftLUTLeft && m_ppdShiftLUTLeft : m_ppiShiftLUTRight && m_ppdShiftLUTRight );
286  AOF(m_auiInputResolution[0] == pcPicYuvDepth->getWidth ());
287  AOF(m_auiInputResolution[1] == pcPicYuvDepth->getHeight());
288
289  PelImage cInputDepth ( pcPicYuvDepth    , true);
290  PelImage cOutputImage( pcUsedSampleMap );
291  PelImage cInputImage ( m_auiInputResolution[0], m_auiInputResolution[1], 1, 2 );
292  cInputImage.assign(0);
293
294  m_pcFilled     ->assign(REN_IS_HOLE);
295  xConvertInputData(  &cInputImage,  &cInputDepth,   m_pcInputImage,  m_pcInputDepth, !bRenderFromLeft );
296  xShiftPixels     (m_pcInputImage, m_pcInputDepth, m_pcOutputImage, m_pcFilled, bRenderFromLeft);
297
298  xCreateAlphaMap  ( m_pcFilled, m_pcFilled, bRenderFromLeft );
299
300  if ( !bRenderFromLeft )
301  {
302    TRenFilter::mirrorHor( m_pcFilled );
303  }
304
305  TRenFilter::filledToUsedPelMap( m_pcFilled, &cOutputImage, m_iUsedPelMapMarExt );
306};
307
308
309Void TRenTop::interpolateView( TComPicYuv* pcPicYuvVideoLeft, TComPicYuv* pcPicYuvDepthLeft, TComPicYuv* pcPicYuvVideoRight, TComPicYuv* pcPicYuvDepthRight, TComPicYuv* pcPicYuvSynthOut, Int iBlendMode, Int iSimEnhBaseView )
310{
311  assert( !m_bExtrapolate );
312  assert( m_auiInputResolution[0] == pcPicYuvVideoLeft ->getWidth () );
313  assert( m_auiInputResolution[1] == pcPicYuvVideoRight->getHeight() );
314
315  AOT( iBlendMode == 3);
316  m_iBlendMode = iBlendMode;
317  m_iSimEnhBaseView = iSimEnhBaseView;
318
319  PelImage cLeftInputImage   ( pcPicYuvVideoLeft  );
320  PelImage cLeftInputDepth   ( pcPicYuvDepthLeft,  true );
321  PelImage cRightInputImage  ( pcPicYuvVideoRight );
322  PelImage cRightInputDepth  ( pcPicYuvDepthRight, true );
323  PelImage cOutputImage      ( pcPicYuvSynthOut   );
324
325  m_pcLeftOutputImage ->init();
326  m_pcRightOutputImage->init();
327  m_pcOutputImage     ->init();
328
329  if ( m_iBlendMode == eRenBlendDepthFirst )
330  {
331    m_pcOutputDepth->init();
332  }
333
334  m_pcLeftFilled ->assign(REN_IS_HOLE);
335  m_pcRightFilled->assign(REN_IS_HOLE);
336
337  xPreProcessDepth(&cLeftInputDepth , &cLeftInputDepth );
338  xPreProcessDepth(&cRightInputDepth, &cRightInputDepth);
339
340  xConvertInputData( &cLeftInputImage,  &cLeftInputDepth,  m_pcLeftInputImage,  m_pcLeftInputDepth  ,false );
341  xConvertInputData( &cRightInputImage, &cRightInputDepth, m_pcRightInputImage, m_pcRightInputDepth ,true  );
342
343  // Render from Left View to Right view
344  if ( m_iBlendMode != eRenBlendDepthFirst )
345  {
346    xShiftPixels(m_pcLeftInputImage,  m_pcLeftInputDepth, m_pcLeftOutputImage, m_pcLeftFilled, true );
347    xFillHoles  (m_pcLeftOutputImage, m_pcLeftFilled,     m_pcLeftOutputImage, true );
348  }
349
350  xShiftPixels(m_pcLeftInputDepth,  m_pcLeftInputDepth, m_pcLeftOutputDepth, m_pcLeftFilled, true );
351  xFillHoles     ( m_pcLeftOutputDepth, m_pcLeftFilled,     m_pcLeftOutputDepth, true);
352  xCreateAlphaMap( m_pcLeftFilled,      m_pcLeftFilled,     true );
353
354  // Render from Right View to Left view
355  if ( m_iBlendMode != eRenBlendDepthFirst )
356  {
357    xShiftPixels(m_pcRightInputImage , m_pcRightInputDepth, m_pcRightOutputImage, m_pcRightFilled, false );
358    xFillHoles  (m_pcRightOutputImage, m_pcRightFilled,     m_pcRightOutputImage, false);
359  }
360
361  xShiftPixels(m_pcRightInputDepth,  m_pcRightInputDepth, m_pcRightOutputDepth, m_pcRightFilled, false);
362  xFillHoles     ( m_pcRightOutputDepth, m_pcRightFilled,     m_pcRightOutputDepth, false);
363  xCreateAlphaMap( m_pcRightFilled,      m_pcRightFilled, false );
364
365  TRenFilter::mirrorHor( m_pcRightOutputImage );
366  TRenFilter::mirrorHor( m_pcRightOutputDepth );
367  TRenFilter::mirrorHor( m_pcRightFilled      );
368
369  xEnhSimilarity( m_pcLeftOutputImage, m_pcRightOutputImage, m_pcLeftFilled, m_pcRightFilled );
370
371  if ( m_iBlendMode == eRenBlendDepthFirst )
372  {
373    xBlend               ( m_pcLeftOutputDepth,  m_pcRightOutputDepth, m_pcLeftFilled,       m_pcRightFilled, m_pcLeftOutputDepth, m_pcRightOutputDepth, m_pcOutputDepth);
374
375    xBackShiftPixels     ( m_pcLeftInputImage,   m_pcOutputDepth,      m_pcLeftOutputImage,  m_pcLeftFilled  , false);
376    xFillHoles           ( m_pcLeftOutputImage,  m_pcLeftFilled,       m_pcLeftOutputImage, false);
377    xCreateAlphaMap      ( m_pcLeftFilled,       m_pcLeftFilled,       true );
378
379    TRenFilter::mirrorHor( m_pcRightInputImage );
380    xBackShiftPixels     ( m_pcRightInputImage,  m_pcOutputDepth,      m_pcRightOutputImage, m_pcRightFilled , true );
381    xFillHoles           ( m_pcRightOutputImage, m_pcRightFilled,      m_pcRightOutputImage, true);
382
383    TRenFilter::mirrorHor( m_pcRightFilled );
384    xCreateAlphaMap      ( m_pcRightFilled,      m_pcRightFilled,      true );
385    TRenFilter::mirrorHor( m_pcRightFilled );
386  }
387
388  xBlend(m_pcLeftOutputImage, m_pcRightOutputImage, m_pcLeftFilled, m_pcRightFilled, m_pcLeftOutputDepth, m_pcRightOutputDepth, m_pcOutputImage);
389  xConvertOutputData( m_pcOutputImage, &cOutputImage , false );
390
391  xPostProcessImage  ( &cOutputImage, &cOutputImage);
392  xCutMargin( &cOutputImage );
393};
394
395
396Void TRenTop::xPreProcessDepth( PelImage* pcInImage, PelImage* pcOutImage )
397{
398  if ( m_iPreProcMode == eRenPreProNone )
399    return;
400
401  PelImage* pcTemp;
402
403  if (pcInImage == pcOutImage)
404  {
405    pcTemp = pcOutImage->create();
406  }
407  else
408  {
409    pcTemp = pcOutImage;
410  }
411
412  pcTemp->assign(pcInImage);
413
414  switch ( m_iPreProcMode )
415  {
416    case eRenPreProBinom:
417      TRenFilter::binominal(pcOutImage, pcTemp, m_iPreFilterSize);
418      break;
419    case eRenPreProNone:
420      break;
421    default:
422      assert(0);
423      break;
424  }
425
426  if (pcInImage == pcOutImage)
427  {
428    pcOutImage->setData(pcTemp, true);
429    delete pcTemp;
430  };
431
432}
433
434Void TRenTop::xShiftPlanePixelsLinInt( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
435{
436  Int iWidth        = apcInputPlanes[0]->getWidth();
437  Int iHeight       = apcInputPlanes[0]->getHeight();
438
439  Int iInputStride  = apcInputPlanes [0]->getStride();
440  Int iOutputStride = apcOutputPlanes[0]->getStride();
441
442  Int iFilledStride = pcFilledPlane->getStride();
443  Int iDepthStride  = pcDepthPlane ->getStride();
444
445  pcFilledPlane->assign(REN_IS_HOLE);
446
447  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
448  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
449
450  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
451  {
452    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
453    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
454    assert( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
455    assert( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
456    assert( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
457  }
458
459  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
460  Pel* pcFilledData = pcFilledPlane->getPlaneData();
461
462  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
463  {
464    Int iPrevShiftedPos = -1;
465    Int iShiftedPos = -1;
466
467    for(Int iPosX = 0; iPosX < iWidth; iPosX ++ )
468    {
469      Bool bExtrapolate = false;
470
471      // compute disparity and shift
472      iShiftedPos  = ( iPosX << m_iRelShiftLUTPrec ) - m_aiShiftLUTCur[RemoveBitIncrement( pcDepthData[iPosX])];
473
474      if (iPosX == 0)
475      {
476        // in first iteration only get dLeftPos
477        iPrevShiftedPos = iShiftedPos;
478        continue;
479      };
480
481      Int iDeltaPos = iShiftedPos - iPrevShiftedPos;
482
483      if ( iDeltaPos <= 0 || (iDeltaPos > (2 << m_iRelShiftLUTPrec)))
484      {
485        // skip Interpolation if pixel is shifted forwards (gap) or if  pixel is shifted backwards (foreground object)
486        bExtrapolate = true;
487      };
488
489      Int iInterPolPos;
490      if (!bExtrapolate)
491      {  // Interpolate between j1 and j2
492        for (iInterPolPos = ( iPrevShiftedPos + (1 << m_iRelShiftLUTPrec) - 1 ) >> m_iRelShiftLUTPrec  ; iInterPolPos <= (iShiftedPos >> m_iRelShiftLUTPrec); iInterPolPos++)
493        {
494          if ( (iInterPolPos >= iWidth) || (iInterPolPos < (Int) 0))
495          {
496            // skip Interpolation if Interpolation position is outside frame
497            continue;
498          };
499
500          // Interpolate
501          Int iDeltaCurPos  = (iInterPolPos << m_iRelShiftLUTPrec) - iPrevShiftedPos;
502          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
503          {
504            Pel cVal  = (( apcInputData[uiCurPlane][iPosX - 1] * iDeltaPos +  ( apcInputData[uiCurPlane][iPosX] - apcInputData[uiCurPlane][iPosX - 1] ) * iDeltaCurPos ) / iDeltaPos );
505            apcOutputData[uiCurPlane][iInterPolPos]  = cVal;
506          }
507
508          pcFilledData[iInterPolPos]  = REN_IS_FILLED;
509        }
510      }
511      else
512      { // Extrapolate right from dLeftPos and left from dRightPos
513        Int iShiftedPosCeiled = (( iPrevShiftedPos + (1 << m_iRelShiftLUTPrec) - 1) >> m_iRelShiftLUTPrec ) << m_iRelShiftLUTPrec;
514        if ( (iPrevShiftedPos + (m_iRelShiftLUTPrec >> 1) ) > iShiftedPosCeiled )
515        {
516          iInterPolPos = iShiftedPosCeiled >> m_iRelShiftLUTPrec;
517
518          if ( (iInterPolPos >= iWidth) || (iInterPolPos < (Int) 0))
519          {
520            // skip Interpolation if Interpolation position is outside frame
521            iPrevShiftedPos = iShiftedPos;
522            continue;
523          };
524
525          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
526          {
527            apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX - 1];
528          }
529
530          pcFilledData[iInterPolPos]  = REN_IS_FILLED;
531        }
532
533        Int iPrevShiftedPosFloor = (iShiftedPos >> m_iRelShiftLUTPrec) << m_iRelShiftLUTPrec;
534        if (iShiftedPos - (m_iRelShiftLUTPrec > 1) < iPrevShiftedPosFloor )
535        {
536          iInterPolPos = iPrevShiftedPosFloor >> m_iRelShiftLUTPrec;
537
538          if ( (iInterPolPos >= iWidth) || (iInterPolPos < (Int) 0))
539          {
540            // skip Interpolation if Interpolation position is outside frame
541            iPrevShiftedPos = iShiftedPos;
542            continue;
543          };
544
545          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
546          {
547            apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX ];
548          }
549
550          pcFilledData[iInterPolPos]  = REN_IS_FILLED;
551        }
552      }
553      iPrevShiftedPos = iShiftedPos;
554    }
555
556    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
557    {
558      apcOutputData[uiCurPlane] += iOutputStride;
559      apcInputData [uiCurPlane] += iInputStride;
560    }
561    pcFilledData += iFilledStride;
562    pcDepthData  += iDepthStride;
563  }
564  delete[] apcInputData;
565  delete[] apcOutputData;
566};
567
568
569Void TRenTop::xShiftPlanePixelsLinReal( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
570{
571  Int iWidth        = apcInputPlanes[0]->getWidth();
572  Int iHeight       = apcInputPlanes[0]->getHeight();
573
574  Int iInputStride  = apcInputPlanes [0]->getStride();
575  Int iOutputStride = apcOutputPlanes[0]->getStride();
576
577  Int iFilledStride = pcFilledPlane->getStride();
578  Int iDepthStride  = pcDepthPlane ->getStride();
579
580  pcFilledPlane->assign( REN_IS_HOLE );
581
582  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
583  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
584
585  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
586  {
587    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
588    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
589    assert( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
590    assert( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
591    assert( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
592  }
593
594  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
595  Pel* pcFilledData = pcFilledPlane->getPlaneData();
596
597  ///// FEM Stuff /////
598  const UInt  cuiMaxPlaneNum = 6;  AOT( uiNumberOfPlanes > cuiMaxPlaneNum );
599  IntImagePlane* apcDiffPlane[ cuiMaxPlaneNum ];
600  Int*          ppiDiffPlanes[ cuiMaxPlaneNum ];
601  Int             iDiffStride = 0;
602
603  if ( m_iInterpolationMode == eRenIntFEM )
604  {
605    AOT( uiNumberOfPlanes > cuiMaxPlaneNum );
606    for ( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
607    {
608      apcDiffPlane[uiCurPlane] = new IntImagePlane( iWidth, iHeight, apcInputPlanes[uiCurPlane]->getPad());
609      TRenFilter::diffHorSym(apcInputPlanes[uiCurPlane] , apcDiffPlane[uiCurPlane]);
610      ppiDiffPlanes[uiCurPlane] = apcDiffPlane[uiCurPlane]->getPlaneData();
611    }
612    iDiffStride = apcDiffPlane[0]->getStride();
613  }
614  ///// FEM Stuff End /////
615
616  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
617  {
618    Double dShiftedPos = 0;
619    Double dPrevShiftedPos = 0;
620
621    for(Int iPosX = 0; iPosX < iWidth; iPosX ++ )
622    {
623        Bool bExtrapolate = false;
624
625        // compute disparity and shift
626        assert( RemoveBitIncrement(pcDepthData[iPosX]) >= 0 && RemoveBitIncrement(pcDepthData[iPosX]) <= 256 );
627        dPrevShiftedPos  = (Double) iPosX - m_adShiftLUTCur[ RemoveBitIncrement(pcDepthData[iPosX])];
628
629        if (iPosX == 0)
630        {
631          // in first iteration only get dLeftPos
632          dShiftedPos = dPrevShiftedPos;
633          continue;
634        };
635
636        Double dDeltaPos = dPrevShiftedPos - dShiftedPos;
637
638        if ((dDeltaPos <= 0) || ( dDeltaPos > 2 ))
639        {
640          // skip Interpolation if pixel is shifted backwards (foreground object)  or if pixel is shifted forwards (gap)
641          bExtrapolate = true;
642        };
643
644        Int iInterPolPos;
645        if (!bExtrapolate)
646        {  // Interpolate between j1 and j2
647          for (iInterPolPos = (Int) ceil(dShiftedPos); iInterPolPos <= floor(dPrevShiftedPos); iInterPolPos++)
648          {
649            if ( (iInterPolPos >= (Int) iWidth) || (iInterPolPos < (Int) 0 ))
650            {
651              // skip Interpolation if Interpolation position is outside frame
652              continue;
653            };
654
655            // Interpolate
656            Pel cVal;
657            if ( m_iInterpolationMode == eRenIntFEM ) //FEM Interpolation
658            {
659              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
660              {
661                cVal  = TRenFilter::interpCHSpline(iInterPolPos, dShiftedPos, dPrevShiftedPos, apcInputData[uiCurPlane][iPosX - 1], ppiDiffPlanes[uiCurPlane][iPosX - 1], apcInputData[uiCurPlane][iPosX], ppiDiffPlanes[uiCurPlane][iPosX] );
662                apcOutputData[uiCurPlane][iInterPolPos]  = cVal;
663              }
664            }
665            else
666            {
667              Double dDeltaJ  = (Double) iInterPolPos - dShiftedPos;
668
669              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
670              {
671                cVal  = (UChar) ( (Double) apcInputData[uiCurPlane][iPosX - 1] +  ( (Double) apcInputData[uiCurPlane][iPosX] - (Double) apcInputData[uiCurPlane][iPosX - 1] ) / dDeltaPos * dDeltaJ + 0.5);
672                apcOutputData[uiCurPlane][iInterPolPos]  = cVal;
673              }
674            };
675
676            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
677          }
678        }
679        else
680        { // Extrapolate right from dLeftPos and left from dRightPos
681          if (dShiftedPos + 0.5 > ceil(dShiftedPos))
682          {
683            iInterPolPos = (Int) ceil(dShiftedPos);
684
685            if ( (iInterPolPos >= (Int) iWidth) || (iInterPolPos < (Int) 0))
686            {
687              // skip Interpolation if Interpolation position is outside frame
688              dShiftedPos = dPrevShiftedPos;
689              continue;
690            };
691
692            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
693            {
694              apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX - 1];
695            }
696
697            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
698          }
699
700          if (dPrevShiftedPos - 0.5 < floor(dPrevShiftedPos))
701          {
702            iInterPolPos = (Int) floor(dPrevShiftedPos);
703
704            if ( (iInterPolPos >= (Int) iWidth) || (iInterPolPos < (Int) 0))
705            {
706              // skip Interpolation if Interpolation position is outside frame
707              dShiftedPos = dPrevShiftedPos;
708              continue;
709            };
710
711            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
712            {
713              apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX ];
714            }
715
716            pcFilledData[iInterPolPos]  = REN_IS_FILLED;
717          }
718        }
719        dShiftedPos = dPrevShiftedPos;
720      }
721
722    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
723    {
724      apcOutputData[uiCurPlane] += iOutputStride;
725      apcInputData [uiCurPlane] += iInputStride;
726
727      if (m_iInterpolationMode ==  eRenIntFEM)
728      {
729        ppiDiffPlanes[ uiCurPlane ] += iDiffStride;
730      }
731    }
732
733    pcFilledData += iFilledStride;
734    pcDepthData  += iDepthStride;
735  }
736
737  if (m_iInterpolationMode ==  eRenIntFEM)
738  {
739    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
740    {
741      delete apcDiffPlane[uiCurPlane];
742    }
743  }
744
745  delete[] apcInputData;
746  delete[] apcOutputData;
747}
748
749
750Void TRenTop::xShiftPlanePixels( PelImagePlane** apcInPlane, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutPlane, PelImagePlane* pcPlaneFilled, UInt uiNumberOfPlanes )
751{
752  switch ( m_iInterpolationMode)
753  {
754  case eRenIntFullPel:
755    xShiftPlanePixelsFullPel( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes);
756    break;
757  case eRenIntFEM:
758  case eRenIntLinReal:
759    xShiftPlanePixelsLinReal( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes);
760    break;
761  case eRenIntLinInt:
762    xShiftPlanePixelsLinInt ( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes);
763    break;
764  case eRenInt8Tap:
765    xShiftPlanePixels8Tap   ( apcInPlane, pcDepthPlane, apcOutPlane, pcPlaneFilled, uiNumberOfPlanes );
766    break;
767  default:
768    AOF( false );
769  }
770}
771
772
773Void TRenTop::xShiftPlanePixelsFullPel( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
774{
775  Int iWidth        = apcInputPlanes[0]->getWidth();
776  Int iHeight       = apcInputPlanes[0]->getHeight();
777
778  Int iInputStride  = apcInputPlanes [0]->getStride();
779  Int iOutputStride = apcOutputPlanes[0]->getStride();
780
781  Int iFilledStride = pcFilledPlane->getStride();
782  Int iDepthStride  = pcDepthPlane ->getStride();
783
784  pcFilledPlane->assign(REN_IS_HOLE);
785
786  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
787  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
788
789  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
790  {
791    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
792    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
793    assert( iWidth        == apcInputPlanes [uiCurPlane]->getWidth()  && iWidth        == apcOutputPlanes[uiCurPlane]->getWidth() );
794    assert( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
795    assert( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
796  }
797
798  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
799  Pel* pcFilledData = pcFilledPlane->getPlaneData();
800
801  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
802  {
803    Int iPrevShiftedPos = -1;
804
805    for(Int iPosX = 0; iPosX < iWidth; iPosX++)
806    {
807      assert( RemoveBitIncrement(pcDepthData[iPosX]) >= 0 && RemoveBitIncrement(pcDepthData[iPosX]) <= 256 );
808      Int iShiftedPos = iPosX - m_aiShiftLUTCur[ RemoveBitIncrement(pcDepthData[iPosX])] ;
809      if (iShiftedPos < iWidth && iShiftedPos >= 0)
810      {
811        Int iDiff = iShiftedPos - iPrevShiftedPos;
812        if (( iDiff <= 2) && (iDiff > 0) )
813        {
814          for (Int iCurPos = iPrevShiftedPos+1; iCurPos <= iShiftedPos; iCurPos++)
815          {
816            for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
817            {
818              apcOutputData[uiCurPlane][iCurPos] = apcInputData[uiCurPlane][iPosX];    // Only small gaps, therefor not necessary NN
819            }
820            pcFilledData[iCurPos] = REN_IS_FILLED;
821          }
822        }
823        else
824        {
825          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
826          {
827            apcOutputData[uiCurPlane][iShiftedPos] = apcInputData[uiCurPlane][iPosX];
828          }
829          pcFilledData[iShiftedPos] = REN_IS_FILLED;
830        }
831        iPrevShiftedPos = iShiftedPos;
832      }
833    }
834    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
835    {
836      apcOutputData[uiCurPlane] += iOutputStride;
837      apcInputData [uiCurPlane] += iInputStride;
838    }
839    pcFilledData += iFilledStride;
840    pcDepthData  += iDepthStride;
841  }
842
843  delete[] apcInputData;
844  delete[] apcOutputData;
845}
846
847Void TRenTop::xBackShiftPlanePixels( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes )
848{
849  Int iOutputWidth  = apcOutputPlanes[0]->getWidth();
850  Int iInputWidth   = apcInputPlanes [0]->getWidth();
851  Int iHeight       = apcInputPlanes [0]->getHeight();
852
853  Int iInputStride  = apcInputPlanes [0]->getStride();
854  Int iOutputStride = apcOutputPlanes[0]->getStride();
855
856  Int iFilledStride = pcFilledPlane->getStride();
857  Int iDepthStride  = pcDepthPlane ->getStride();
858
859  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
860  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
861
862  Int iStep         = (1 << m_iRelShiftLUTPrec);
863
864  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
865  {
866    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
867    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
868    AOF( iInputWidth   == apcInputPlanes [uiCurPlane]->getWidth()  && iOutputWidth  == apcOutputPlanes[uiCurPlane]->getWidth() );
869    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
870    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
871    AOF( iInputWidth   == iOutputWidth * iStep );
872  }
873
874  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
875  Pel* pcFilledData = pcFilledPlane->getPlaneData();
876
877
878  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
879  {
880    for(Int iPosX = 0; iPosX < iOutputWidth; iPosX ++)
881    {
882      Int iBackShiftedPos = (iPosX << m_iRelShiftLUTPrec) - m_aiShiftLUTCur[ RemoveBitIncrement( pcDepthData[iPosX] )];
883      if( ( pcFilledData[iPosX] == REN_IS_FILLED )  && (iBackShiftedPos >= 0 ) && ( iBackShiftedPos < iInputWidth ) )
884      {
885        for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
886        {
887          apcOutputData[uiCurPlane][iPosX] = apcInputData[uiCurPlane][iBackShiftedPos];
888        }
889      }
890      else
891      {
892        for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
893        {
894          apcOutputData[uiCurPlane][iPosX] = 0;
895        }
896        pcFilledData[iPosX] = REN_IS_HOLE;
897      }
898    }
899
900    for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
901    {
902      apcOutputData[uiCurPlane] += iOutputStride;
903      apcInputData [uiCurPlane] += iInputStride;
904    }
905    pcFilledData += iFilledStride;
906    pcDepthData  += iDepthStride;
907  }
908
909  delete[] apcInputData;
910  delete[] apcOutputData;
911}
912
913Void TRenTop::xShiftPlanePixels8Tap( PelImagePlane** apcInputPlanes, PelImagePlane* pcDepthPlane, PelImagePlane** apcOutputPlanes, PelImagePlane* pcFilledPlane, UInt uiNumberOfPlanes  )
914{
915  Bool bRenderDepth = (apcInputPlanes[0] == pcDepthPlane);
916
917  Int iOutputWidth  = apcOutputPlanes[0]->getWidth();
918  Int iInputWidth   = apcInputPlanes [0]->getWidth();
919  Int iHeight       = apcInputPlanes [0]->getHeight();
920
921  Int iInputStride  = apcInputPlanes [0]->getStride();
922  Int iOutputStride = apcOutputPlanes[0]->getStride();
923
924  Int iFilledStride = pcFilledPlane->getStride();
925  Int iDepthStride  = pcDepthPlane ->getStride();
926
927  Int iStep         = (1 << m_iRelShiftLUTPrec);
928
929  pcFilledPlane->assign(REN_IS_HOLE);
930
931  Pel** apcInputData  = new Pel*[ uiNumberOfPlanes ];
932  Pel** apcOutputData = new Pel*[ uiNumberOfPlanes ];
933
934  for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
935  {
936    apcInputData   [uiCurPlane] = apcInputPlanes [uiCurPlane]->getPlaneData();
937    apcOutputData  [uiCurPlane] = apcOutputPlanes[uiCurPlane]->getPlaneData();
938    AOF( iInputWidth   == apcInputPlanes [uiCurPlane]->getWidth()  && iOutputWidth  == apcOutputPlanes[uiCurPlane]->getWidth() );
939    AOF( iHeight       == apcInputPlanes [uiCurPlane]->getHeight() && iHeight       == apcOutputPlanes[uiCurPlane]->getHeight());
940    AOF( iInputStride  == apcInputPlanes [uiCurPlane]->getStride() && iOutputStride == apcOutputPlanes[uiCurPlane]->getStride());
941    AOF( iInputWidth   == iOutputWidth * iStep );
942  }
943
944  Pel* pcDepthData  = pcDepthPlane ->getPlaneData();
945  Pel* pcFilledData = pcFilledPlane->getPlaneData();
946
947  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
948  {
949    Int iPrevShiftedPos = -1;
950    Int iShiftedPos     = -1;
951
952    for(Int iPosX = 0; iPosX < iInputWidth; iPosX += iStep )
953    {
954      // compute disparity and shift
955      iShiftedPos  =  iPosX - m_aiShiftLUTCur[RemoveBitIncrement(pcDepthData[iPosX])];
956
957      if ( iPosX == 0 )
958      {
959        // in first iteration only get dLeftPos
960        iPrevShiftedPos = iShiftedPos;
961        continue;
962      };
963
964      Int iDeltaPos = iShiftedPos - iPrevShiftedPos;
965
966      Bool bDisocclusion = ( iDeltaPos > (2 << m_iRelShiftLUTPrec) );
967      Bool bOcclusion    = ( iDeltaPos <= 0 );
968
969      Int iInterPolPos;
970      if ( !bDisocclusion && !bOcclusion )
971      {  // Interpolate between previous shifted pos and shifted pos
972        for (iInterPolPos = xCeil( iPrevShiftedPos ); iInterPolPos <= xCeil (iShiftedPos ) -1 ; iInterPolPos++)
973        {
974          if ( (iInterPolPos < (Int) 0) || (iInterPolPos >= iOutputWidth))
975          {
976            // skip Interpolation if Interpolation position is outside frame
977            continue;
978          };
979
980          // Interpolate
981          Int iDeltaCurPos  = (iInterPolPos << m_iRelShiftLUTPrec) - iPrevShiftedPos;
982
983          AOF( (iDeltaCurPos <= iDeltaPos) && ( iDeltaCurPos >= 0));
984          AOF( iDeltaPos    <= (2 <<  m_iRelShiftLUTPrec)  );
985          AOF( m_aaiSubPelShift[iDeltaPos][iDeltaCurPos] != 0xdeaddead);
986
987          Int iSourcePos;
988
989          if ( bRenderDepth )
990          {
991            iSourcePos = iPosX - iStep; // Render depth with Full Pel accuracy to avoid ringing at sharp depth edges;
992          }
993          else
994          {
995            iSourcePos = iPosX +  m_aaiSubPelShift[iDeltaPos][iDeltaCurPos];   // GT:  = iPosX - iStep + ( iStep * iDeltaCurPos + ( iDeltaPos >> 1) ) / iDeltaPos;
996          }
997
998          for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
999          {
1000            apcOutputData[uiCurPlane][iInterPolPos] = apcInputData[uiCurPlane][iSourcePos];
1001          }
1002
1003          pcFilledData[ iInterPolPos]  = REN_IS_FILLED;
1004        }
1005      }
1006      else
1007        {
1008        // Fill Disocclusion Edge
1009
1010        if ( bDisocclusion )
1011        {
1012          Int iPrevShiftedPosCeiled =  xCeil(iPrevShiftedPos) << m_iRelShiftLUTPrec;
1013          iInterPolPos = iPrevShiftedPosCeiled >> m_iRelShiftLUTPrec;
1014
1015          if ((iPrevShiftedPos + (iStep >> 1) ) > iPrevShiftedPosCeiled )
1016          {
1017            if ( !((iInterPolPos < (Int) 0) || (iInterPolPos >= iOutputWidth)))
1018            {
1019
1020              for( UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++)
1021              {
1022                apcOutputData[uiCurPlane][iInterPolPos]  = apcInputData[uiCurPlane][iPosX - iStep];
1023              }
1024              pcFilledData[iInterPolPos]  = REN_IS_FILLED;
1025
1026            }           
1027            iInterPolPos++;
1028          }         
1029
1030          // Fill Disocclusion
1031          if ( m_bInstantHoleFilling )
1032          {
1033            for ( ; iInterPolPos <= xCeil (iShiftedPos ) -1 ; iInterPolPos++)
1034            {
1035              if ( ( 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::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  AOF( g_bitDepthC == g_bitDepthY ); 
1603  AOT( m_iSimEnhBaseView != 1 && m_iSimEnhBaseView != 2 );
1604  Int iWidth  = (*apcRightPlane)->getWidth ();
1605  Int iHeight = (*apcRightPlane)->getHeight();
1606
1607  Int* aiHistLeft  = new Int[ ((Int64)1 ) << g_bitDepthY ];
1608  Int* aiHistRight = new Int[ ((Int64)1 ) << g_bitDepthY ];
1609  Pel* aiConvLUT   = new Pel[ ((Int64)1 ) << g_bitDepthY ];
1610
1611  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1612  {
1613    for (Int iCurVal = 0 ; iCurVal < ( 1 << g_bitDepthY ); iCurVal++)
1614    {
1615      aiHistLeft [iCurVal] = 0;
1616      aiHistRight[iCurVal] = 0;
1617    }
1618
1619    Pel* pcFilledRightData = pcFilledRightPlane    ->getPlaneData();
1620    Pel* pcRightImageData  = (*apcRightPlane )     ->getPlaneData();
1621
1622    Pel* pcFilledLeftData  = pcFilledLeftPlane     ->getPlaneData();
1623    Pel* pcLeftImageData   = (*apcLeftPlane)       ->getPlaneData();
1624
1625 
1626
1627    for (UInt uiYPos = 0; uiYPos < iHeight; uiYPos++ )
1628    {
1629      for (UInt uiXPos = 0; uiXPos < iWidth; uiXPos++ )
1630      {
1631          if      ( pcFilledLeftData[uiXPos] == REN_IS_FILLED &&  pcFilledRightData[uiXPos] == REN_IS_FILLED )
1632          {
1633            aiHistLeft [pcLeftImageData   [uiXPos] ]++;
1634            aiHistRight[pcRightImageData  [uiXPos] ]++;
1635          }
1636      }
1637
1638
1639      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1640      pcRightImageData  += (*apcRightPlane)       ->getStride();
1641
1642      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1643      pcLeftImageData   +=  (*apcLeftPlane)       ->getStride();
1644    }
1645
1646    Int iCumSumChange  = 0;
1647    Int iCumSumBase    = 0;
1648    Int iCurBaseVal    = 0;
1649    Int iCurChangeVal  = 0;
1650
1651    Int* aiHistChange  = (m_iSimEnhBaseView == 2 ) ? aiHistLeft  : aiHistRight;
1652    Int* aiHistBase    = (m_iSimEnhBaseView == 2 ) ? aiHistRight : aiHistLeft ;
1653
1654    iCumSumChange += aiHistChange[iCurChangeVal];
1655    iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1656
1657    Int iCheckSumLeft  = 0;
1658    Int iCheckSumRight = 0;
1659
1660    for (Int iCurVal = 0 ; iCurVal < ( 1 << g_bitDepthY ); iCurVal++)
1661    {
1662      iCheckSumLeft  += aiHistLeft [iCurVal];
1663      iCheckSumRight += aiHistRight[iCurVal];
1664    }
1665
1666
1667    while( iCurChangeVal < ( 1 << g_bitDepthY ) )
1668    {
1669      if ( iCumSumBase == iCumSumChange )
1670      {
1671        aiConvLUT[iCurChangeVal] = std::min( iCurBaseVal,  ( 1 << g_bitDepthY ) - 1 );
1672        iCurBaseVal  ++;
1673        iCurChangeVal++;
1674        iCumSumChange += aiHistChange[iCurChangeVal];
1675        if (iCurBaseVal <  ( 1 << g_bitDepthY ) )
1676        {
1677          iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1678        }
1679      }
1680      else if ( iCumSumBase < iCumSumChange )
1681      {
1682        iCurBaseVal++;
1683        if (iCurBaseVal < ( 1 << g_bitDepthY ) )
1684        {
1685          iCumSumBase   += aiHistBase  [iCurBaseVal]  ;
1686        }
1687      }
1688      else if ( iCumSumBase > iCumSumChange)
1689      {
1690        aiConvLUT[iCurChangeVal] = std::min(iCurBaseVal, ( 1 << g_bitDepthY )-1);
1691        iCurChangeVal++;
1692        iCumSumChange += aiHistChange  [iCurChangeVal]  ;
1693      }
1694    }
1695
1696    Pel* pcChangeImageData   = ( ( m_iSimEnhBaseView == 2 ) ? (*apcLeftPlane) : (*apcRightPlane) )->getPlaneData();
1697    Int  iChangeImageStride  = ( ( m_iSimEnhBaseView == 2 ) ? (*apcLeftPlane) : (*apcRightPlane) )->getStride   ();
1698
1699    for (UInt uiYPos = 0; uiYPos < iHeight; uiYPos++ )
1700    {
1701      for (UInt uiXPos = 0; uiXPos < iWidth; uiXPos++ )
1702      {
1703          pcChangeImageData  [uiXPos] = aiConvLUT[ pcChangeImageData[uiXPos]];
1704      }
1705      pcChangeImageData   +=  iChangeImageStride;
1706    }
1707
1708    apcRightPlane ++;
1709    apcLeftPlane  ++;
1710
1711  }
1712
1713delete[] aiHistLeft ;
1714delete[] aiHistRight;
1715delete[] aiConvLUT  ;
1716}
1717
1718
1719Void TRenTop::xBlend( PelImage* pcLeftImage, PelImage* pcRightImage, PelImage* pcFilledLeft, PelImage* pcFilledRight, PelImage* pcLeftDepth, PelImage* pcRightDepth, PelImage* pcOutputImage )
1720{
1721  UInt uiNumFullPlanes = pcLeftImage->getNumberOfFullPlanes();
1722  UInt uiNumQuatPlanes = pcLeftImage->getNumberOfQuaterPlanes();
1723
1724  assert( uiNumFullPlanes == pcRightImage->getNumberOfFullPlanes  () && uiNumFullPlanes == pcOutputImage->getNumberOfFullPlanes    ());
1725  assert( uiNumQuatPlanes == pcRightImage->getNumberOfQuaterPlanes() && uiNumQuatPlanes == pcOutputImage->getNumberOfQuaterPlanes  ());
1726
1727  if (uiNumQuatPlanes > 0)
1728  {
1729    assert( pcLeftDepth ->getNumberOfPlanes() > 1 || pcFilledLeft ->getNumberOfPlanes() > 1);
1730    assert( pcRightDepth->getNumberOfPlanes() > 1 || pcFilledRight->getNumberOfPlanes() > 1);
1731  };
1732
1733  switch (m_iBlendMode)
1734  {
1735  case eRenBlendAverg:
1736  case eRenBlendDepthFirst:
1737    xBlendPlanesAvg( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), pcLeftDepth->getPlane(0), pcRightDepth->getPlane(0), pcOutputImage->getPlanes(), uiNumFullPlanes);
1738    if (uiNumQuatPlanes > 0)
1739    {
1740      xBlendPlanesAvg( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), pcLeftDepth->getPlane(1), pcRightDepth->getPlane(1), pcOutputImage->getPlanes()+uiNumFullPlanes, uiNumQuatPlanes);
1741    }
1742    break;
1743  case eRenBlendLeft:
1744  case eRenBlendRight:
1745    xBlendPlanesOneView( pcLeftImage->getPlanes()                , pcRightImage->getPlanes()                , pcFilledLeft->getPlane(0), pcFilledRight->getPlane(0), pcLeftDepth->getPlane(0), pcRightDepth->getPlane(0), pcOutputImage->getPlanes(), uiNumFullPlanes);
1746    if (uiNumQuatPlanes > 0)
1747    {
1748      xBlendPlanesOneView( pcLeftImage->getPlanes()+uiNumFullPlanes, pcRightImage->getPlanes()+uiNumFullPlanes, pcFilledLeft->getPlane(1), pcFilledRight->getPlane(1), pcLeftDepth->getPlane(1), pcRightDepth->getPlane(1), pcOutputImage->getPlanes()+uiNumFullPlanes, uiNumQuatPlanes);
1749    }
1750    break;
1751  }
1752}
1753
1754Void TRenTop::xBlendPlanesOneView( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, PelImagePlane* pcLeftDepthPlane, PelImagePlane* pcRightDepthPlane, PelImagePlane** apcOutputImagePlane, UInt uiNumberOfPlanes )
1755{
1756  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1757  {
1758    Pel* pcFilledRightData = pcFilledRightPlane    ->getPlaneData();
1759    Pel* pcRightImageData  = (*apcRightPlane )     ->getPlaneData();
1760    Pel* pcRightDepthData  = pcRightDepthPlane     ->getPlaneData();
1761
1762    Pel* pcFilledLeftData  = pcFilledLeftPlane     ->getPlaneData();
1763    Pel* pcLeftImageData   = (*apcLeftPlane)       ->getPlaneData();
1764    Pel* pcLeftDepthData   = pcLeftDepthPlane      ->getPlaneData();
1765    Pel* pcOutputData      = (*apcOutputImagePlane)->getPlaneData();
1766
1767    for (UInt uiYPos = 0; uiYPos < (*apcOutputImagePlane)->getHeight(); uiYPos++ )
1768    {
1769      for (UInt uiXPos = 0; uiXPos < (*apcOutputImagePlane)->getWidth(); uiXPos++ )
1770      {
1771        if      (m_iBlendMode == eRenBlendLeft  )
1772        {
1773          if      ( pcFilledLeftData[uiXPos] == REN_IS_FILLED ||  pcFilledRightData[uiXPos] == REN_IS_HOLE )
1774          {
1775            pcOutputData[uiXPos] = pcLeftImageData[uiXPos];
1776          }
1777          else if ( pcFilledLeftData[uiXPos] == REN_IS_HOLE )
1778          {
1779            pcOutputData[uiXPos] = pcRightImageData[uiXPos];
1780          }
1781          else
1782          {
1783            pcOutputData[uiXPos] = pcRightImageData[uiXPos] +  (Pel) (  ( (Int) ( pcLeftImageData[uiXPos] - pcRightImageData[uiXPos] ) * pcFilledLeftData[uiXPos] + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1784          }
1785        }
1786        else if ( m_iBlendMode == eRenBlendRight )
1787        {
1788          if      ( pcFilledRightData[uiXPos] == REN_IS_FILLED || pcFilledLeftData[uiXPos] == REN_IS_HOLE )
1789          {
1790            pcOutputData[uiXPos] = pcRightImageData[uiXPos];
1791          }
1792          else if ( pcFilledRightData[uiXPos] == REN_IS_HOLE )
1793          {
1794            pcOutputData[uiXPos] = pcLeftImageData[uiXPos];
1795          }
1796          else
1797          {
1798            pcOutputData[uiXPos] = pcLeftImageData[uiXPos] +  (Pel) (  ( (Int) ( pcRightImageData[uiXPos] - pcLeftImageData[uiXPos] ) * pcFilledRightData[uiXPos] + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1799          }
1800        }
1801        else
1802        {
1803          AOT(true);
1804        }
1805      }
1806
1807      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1808      pcRightImageData  += (*apcRightPlane)       ->getStride();
1809      pcRightDepthData  +=    pcRightDepthPlane   ->getStride();
1810
1811      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1812      pcLeftImageData   +=  (*apcLeftPlane)       ->getStride();
1813      pcLeftDepthData   +=    pcLeftDepthPlane    ->getStride();
1814      pcOutputData      +=  (*apcOutputImagePlane)->getStride();
1815    }
1816
1817    apcRightPlane ++;
1818    apcLeftPlane  ++;
1819    apcOutputImagePlane++;
1820  }
1821}
1822
1823Void TRenTop::xBlendPlanesAvg( PelImagePlane** apcLeftPlane, PelImagePlane** apcRightPlane, PelImagePlane* pcFilledLeftPlane, PelImagePlane* pcFilledRightPlane, PelImagePlane* pcLeftDepthPlane, PelImagePlane* pcRightDepthPlane, PelImagePlane** apcOutputImagePlane, UInt uiNumberOfPlanes )
1824{
1825  for (UInt uiCurPlane = 0; uiCurPlane < uiNumberOfPlanes; uiCurPlane++ )
1826  {
1827    Pel* pcFilledRightData = pcFilledRightPlane   ->getPlaneData();
1828    Pel* pcRightVideoData  = (*apcRightPlane )    ->getPlaneData();
1829    Pel* pcRightDepthData  = pcRightDepthPlane    ->getPlaneData();
1830
1831    Pel* pcFilledLeftData  = pcFilledLeftPlane    ->getPlaneData();
1832    Pel* pcLeftVideoData   = (*apcLeftPlane)      ->getPlaneData();
1833    Pel* pcLeftDepthData   = pcLeftDepthPlane     ->getPlaneData();
1834
1835    Pel* pcOutputData      = (*apcOutputImagePlane)->getPlaneData();
1836
1837    for (UInt uiYPos = 0; uiYPos < (*apcOutputImagePlane)->getHeight(); uiYPos++ )
1838    {
1839      for (UInt uiXPos = 0; uiXPos < (*apcOutputImagePlane)->getWidth(); uiXPos++ )
1840      {
1841        if      (  (pcFilledRightData[uiXPos] != REN_IS_HOLE ) && ( pcFilledLeftData[uiXPos] != REN_IS_HOLE) )
1842        {
1843          Int iDepthDifference  = m_piInvZLUTLeft[RemoveBitIncrement(pcLeftDepthData[uiXPos])] - m_piInvZLUTRight[RemoveBitIncrement(pcRightDepthData[uiXPos])];
1844
1845          if ( abs ( iDepthDifference ) <= m_iBlendZThres )
1846          {
1847            if      ((pcFilledRightData[uiXPos] == REN_IS_FILLED) && ( pcFilledLeftData[uiXPos] != REN_IS_FILLED))
1848            {
1849              pcOutputData[uiXPos] = pcRightVideoData[uiXPos] +  (Pel) (  ( (Int) ( pcLeftVideoData[uiXPos] - pcRightVideoData[uiXPos] ) * (pcFilledLeftData[uiXPos]) + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1850            }
1851            else if ((pcFilledRightData[uiXPos] != REN_IS_FILLED) && ( pcFilledLeftData[uiXPos] == REN_IS_FILLED))
1852            {
1853              pcOutputData[uiXPos] = pcLeftVideoData[uiXPos]  +  (Pel) (  ( (Int) ( pcRightVideoData[uiXPos] - pcLeftVideoData[uiXPos] ) * (pcFilledRightData[uiXPos]) + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1854            }
1855            else
1856            {
1857              pcOutputData[uiXPos] = pcLeftVideoData[uiXPos]  +  (Pel) (  ( (Int) ( pcRightVideoData[uiXPos] - pcLeftVideoData[uiXPos] ) * m_iBlendDistWeight               + (1 << (REN_VDWEIGHT_PREC - 1)) ) >> REN_VDWEIGHT_PREC );
1858            }
1859
1860          }
1861          else if ( iDepthDifference < 0 )
1862          {
1863            pcOutputData[uiXPos] = pcRightVideoData[uiXPos];
1864          }
1865          else
1866          {
1867            pcOutputData[uiXPos] = pcLeftVideoData[uiXPos];
1868          }
1869        }
1870        else if ( (pcFilledRightData[uiXPos] == REN_IS_HOLE) && (pcFilledLeftData[uiXPos] == REN_IS_HOLE))
1871        {
1872          pcOutputData[uiXPos] = m_piInvZLUTLeft[RemoveBitIncrement( pcLeftDepthData[uiXPos])]  < m_piInvZLUTRight[RemoveBitIncrement(pcRightDepthData[uiXPos])] ? pcLeftVideoData[uiXPos] : pcRightVideoData[uiXPos];
1873        }
1874        else
1875        {
1876          pcOutputData[uiXPos] =  (pcFilledLeftData[uiXPos] == REN_IS_HOLE) ? pcRightVideoData[uiXPos] : pcLeftVideoData[uiXPos];
1877        }
1878      }
1879
1880      pcFilledRightData +=    pcFilledRightPlane  ->getStride();
1881      pcRightVideoData  += (*apcRightPlane)      ->getStride();
1882      pcRightDepthData  +=    pcRightDepthPlane   ->getStride();
1883
1884      pcFilledLeftData  +=    pcFilledLeftPlane   ->getStride();
1885      pcLeftVideoData   +=  (*apcLeftPlane)       ->getStride();
1886      pcLeftDepthData   +=    pcLeftDepthPlane    ->getStride();
1887      pcOutputData      +=  (*apcOutputImagePlane)->getStride();
1888    };
1889
1890    apcRightPlane ++;
1891    apcLeftPlane  ++;
1892    apcOutputImagePlane++;
1893  }
1894}
1895
1896// Temporal Filter from Zhejiang University: (a little different from m16041: Temporal Improvement Method in View Synthesis)
1897Void TRenTop::temporalFilterVSRS( TComPicYuv* pcPicYuvVideoCur, TComPicYuv* pcPicYuvDepthCur, TComPicYuv* pcPicYuvVideoLast, TComPicYuv* pcPicYuvDepthLast, Bool bFirstFrame )
1898{
1899  AOF( g_bitDepthY == g_bitDepthC ); 
1900  Int iSADThres  = 100 ;  //threshold of sad in 4*4 block motion detection
1901
1902  Int iWidth  = m_auiInputResolution[0];
1903  Int iHeight = m_auiInputResolution[1];
1904
1905  //internal variables
1906  Int* piFlagMoving =  m_aiBlkMoving + 2;
1907
1908  Int iVideoCurStride     = pcPicYuvVideoCur ->getStride();
1909  Int iVideoLastStride    = pcPicYuvVideoLast->getStride();
1910  Int iDepthCurStride     = pcPicYuvDepthCur ->getStride();
1911  Int iDepthLastStride    = pcPicYuvDepthLast->getStride();
1912
1913  Pel* pcVideoCurData     = pcPicYuvVideoCur ->getLumaAddr();
1914  Pel* pcVideoLastData    = pcPicYuvVideoLast->getLumaAddr();
1915  Pel* pcDepthCurData     = pcPicYuvDepthCur ->getLumaAddr();
1916  Pel* pcDepthLastData    = pcPicYuvDepthLast->getLumaAddr();
1917
1918  Pel* pcVideoCurDataFrm  = pcVideoCurData ;
1919  Pel* pcVideoLastDataFrm = pcVideoLastData;
1920  Pel* pcDepthCurDataFrm  = pcDepthCurData ;
1921  Pel* pcDepthLastDataFrm = pcDepthLastData;
1922
1923
1924  if( !bFirstFrame ) // first frame need not the weighting, but need to prepare the data
1925  {
1926    for ( Int iPosY = 0; iPosY < (iHeight >> 2); iPosY++)
1927    {
1928      //motion detection by SAD
1929      for ( Int iPosX = 0; iPosX < (iWidth >> 2);  iPosX++)
1930      {
1931        Int iSAD = 0;
1932
1933        Pel* pcVideoCurDataBlk  = pcVideoCurDataFrm  + (iPosX << 2);
1934        Pel* pcVideoLastDataBlk = pcVideoLastDataFrm + (iPosX << 2);
1935
1936        //GT: Check difference of block compared to last frame
1937        for( Int iCurPosY = 0; iCurPosY < 4; iCurPosY++)
1938        {
1939          for( Int iCurPosX = 0; iCurPosX < 4; iCurPosX++)
1940          {
1941            iSAD += abs( pcVideoLastDataBlk[iCurPosX] - pcVideoCurDataBlk[iCurPosX] );   //SAD
1942          }
1943          pcVideoLastDataBlk += iVideoLastStride;
1944          pcVideoCurDataBlk  += iVideoCurStride;
1945        }
1946
1947        piFlagMoving[iPosX] = ( iSAD < iSADThres ) ? 0 : 1;
1948      }
1949
1950      //temporal weighting according to motion detection result -- do a line
1951      for ( Int iPosX = 0; iPosX < (iWidth >> 2);  iPosX++)
1952      {
1953        //5 block
1954       Int iSumMoving = piFlagMoving[iPosX-2] + piFlagMoving[iPosX-1] + piFlagMoving[iPosX]   + piFlagMoving[iPosX+1] + piFlagMoving[iPosX+2];
1955
1956        if( iSumMoving == 0 ) // if not moving
1957        {
1958          Pel* pcDepthCurDataBlk  = pcDepthCurDataFrm  + (iPosX << 2);
1959          Pel* pcDepthLastDataBlk = pcDepthLastDataFrm + (iPosX << 2);
1960
1961          for( Int iCurPosY = 0; iCurPosY < 4; iCurPosY++)
1962          {
1963            for( Int iCurPosX = 0; iCurPosX < 4; iCurPosX++)
1964            { //Weight: 0.75
1965              Int iFilt = (( (pcDepthLastDataBlk[iCurPosX] << 1 ) + pcDepthLastDataBlk[iCurPosX] + pcDepthCurDataBlk[iCurPosX] + 2 ) >> 2 );
1966              assert( (iFilt >= 0) && (iFilt <  ( 1 << g_bitDepthY ) ) );
1967              pcDepthCurDataBlk[iCurPosX] = pcDepthLastDataBlk[iCurPosX];
1968              pcDepthCurDataBlk[iCurPosX] = iFilt;
1969            }
1970
1971            pcDepthCurDataBlk  += iDepthCurStride;
1972            pcDepthLastDataBlk += iDepthLastStride;
1973          }
1974        }
1975      }
1976
1977      pcDepthCurDataFrm  += ( iDepthCurStride  << 2);
1978      pcDepthLastDataFrm += ( iDepthLastStride << 2);
1979      pcVideoCurDataFrm  += ( iVideoCurStride  << 2);
1980      pcVideoLastDataFrm += ( iVideoLastStride << 2);
1981    }
1982  }
1983  pcPicYuvVideoCur->copyToPic( pcPicYuvVideoLast );
1984  pcPicYuvDepthCur->copyToPic( pcPicYuvDepthLast );
1985}
1986
1987TRenTop::TRenTop()
1988{
1989  m_auiInputResolution[0] = 0;
1990  m_auiInputResolution[1] = 0;
1991
1992  // Sub Pel Rendering
1993  m_iLog2SamplingFactor = 0;
1994
1995  // ColorPlaneHandling
1996  m_bUVUp = true;
1997
1998
1999  //PreProcessing
2000  m_iPreProcMode         = eRenPreProNone;
2001  m_iPreFilterSize = 2;
2002
2003  // Interpolation
2004  m_iInterpolationMode   = eRenIntFullPel;
2005
2006  // Sim Enhancement
2007  m_iSimEnhBaseView      = 0;
2008
2009  // Blending
2010  m_iBlendMode           = eRenBlendAverg;
2011  m_iBlendZThresPerc     = -1;
2012  m_bBlendUseDistWeight  = false;
2013  m_iBlendHoleMargin     = -1;
2014
2015  m_iBlendZThres         = -1;
2016  m_iBlendDistWeight     = -1;
2017
2018  // Hole Filling
2019  m_iHoleFillingMode     = eRenHFLWBackExt;
2020  m_bInstantHoleFilling  = false;
2021
2022  // PostProcessing
2023  m_iPostProcMode        = eRenPostProNone;
2024
2025  // Cut
2026  m_auiCut[0] = 0;
2027  m_auiCut[1] = 0;
2028
2029  // Data
2030  m_uiSampledWidth = -1;
2031
2032  // LUTs
2033  m_ppdShiftLUTLeft  = 0;
2034  m_ppdShiftLUTRight = 0;
2035
2036  m_ppdShiftLUTRightMirror    = new Double*[2];
2037  m_ppdShiftLUTRightMirror[0] = new Double [257];
2038  m_ppdShiftLUTRightMirror[1] = new Double [257];
2039
2040  m_adShiftLUTCur    = 0;
2041
2042  m_ppiShiftLUTLeft  = 0;
2043  m_ppiShiftLUTRight = 0;
2044  m_ppiShiftLUTRightMirror    = new Int*[2];
2045  m_ppiShiftLUTRightMirror[0] = new Int[257];
2046  m_ppiShiftLUTRightMirror[1] = new Int[257];
2047
2048  m_aiShiftLUTCur    = 0;
2049  m_piInvZLUTLeft  = new Int[257];
2050  m_piInvZLUTRight = new Int[257];
2051
2052  // Buffers
2053  m_pcLeftInputImage   = 0;
2054  m_pcLeftInputDepth   = 0;
2055  m_pcLeftOutputImage  = 0;
2056  m_pcLeftOutputDepth  = 0;
2057  m_pcLeftFilled       = 0;
2058
2059  m_pcRightInputImage  = 0;
2060  m_pcRightInputDepth  = 0;
2061  m_pcRightOutputImage = 0;
2062  m_pcRightOutputDepth = 0;
2063  m_pcRightFilled      = 0;
2064
2065  m_pcOutputImage      = 0;
2066  m_pcOutputDepth      = 0;
2067
2068  //Extrapolation
2069  m_pcInputImage       = 0;
2070  m_pcInputDepth       = 0;
2071  m_pcFilled           = 0;
2072
2073  // SubPel
2074  m_aaiSubPelShift     = 0;
2075
2076  // Temp
2077  m_pcTempImage        = 0;
2078
2079  //Temporal Filter
2080  m_aiBlkMoving        = 0;
2081}
2082
2083
2084Void TRenTop::init(UInt uiImageWidth,
2085                   UInt uiImageHeight,
2086                   Bool  bExtrapolate,
2087                   UInt uiLog2SamplingFactor,
2088                   Int   iShiftLUTPrec,
2089                   Bool  bUVUp,
2090                   Int   iPreProcMode,
2091                   Int   iPreFilterKernelSize,
2092                   Int   iBlendMode,
2093                   Int   iBlendZThresPerc,
2094                   Bool  bBlendUseDistWeight,
2095                   Int   iBlendHoleMargin,
2096                   Int   iInterpolationMode,
2097                   Int   iHoleFillingMode,
2098                   Int   iPostProcMode,
2099                   Int   iUsedPelMapMarExt
2100                   )
2101
2102{
2103  // Shift LUT Prec
2104  m_iRelShiftLUTPrec = iShiftLUTPrec - (Int) uiLog2SamplingFactor;
2105
2106  // Sub Pel Rendering
2107  m_iLog2SamplingFactor = uiLog2SamplingFactor;
2108
2109  // Extrapolation ?
2110  m_bExtrapolate = bExtrapolate;
2111
2112  // ColorPlaneHandling
2113  m_bUVUp = bUVUp;
2114
2115  //PreProcessing
2116  m_iPreProcMode = iPreProcMode;
2117  m_iPreFilterSize = iPreFilterKernelSize;
2118
2119  // Interpolation
2120  m_iInterpolationMode = iInterpolationMode;
2121
2122  //Blending
2123  m_iBlendMode          = iBlendMode;
2124  m_iBlendZThresPerc    = iBlendZThresPerc;
2125  m_bBlendUseDistWeight = bBlendUseDistWeight;
2126  m_iBlendHoleMargin    = iBlendHoleMargin;
2127
2128  // Hole Filling
2129  m_iHoleFillingMode = iHoleFillingMode;
2130
2131  m_bInstantHoleFilling   = (m_iInterpolationMode == eRenInt8Tap ) && (m_iHoleFillingMode != 0 );
2132
2133  // PostProcessing
2134  m_iPostProcMode    = iPostProcMode;
2135
2136  // Used pel map
2137  m_iUsedPelMapMarExt     = iUsedPelMapMarExt;
2138
2139  // Cut
2140  m_auiCut[0] = 0;
2141  m_auiCut[1] = 0;
2142
2143  m_auiInputResolution[0] = uiImageWidth;
2144  m_auiInputResolution[1] = uiImageHeight;
2145
2146  if ( m_bExtrapolate )
2147  {
2148    PelImage*    pcDump        = 0;
2149    xGetDataPointers( m_pcInputImage, m_pcOutputImage, m_pcInputDepth, pcDump, m_pcFilled, false );
2150  }
2151  else
2152  {
2153    xGetDataPointers(m_pcLeftInputImage,  m_pcLeftOutputImage,  m_pcLeftInputDepth,  m_pcLeftOutputDepth,  m_pcLeftFilled,  true);
2154    xGetDataPointers(m_pcRightInputImage, m_pcRightOutputImage, m_pcRightInputDepth, m_pcRightOutputDepth, m_pcRightFilled, true);
2155    xGetDataPointerOutputImage(m_pcOutputImage, m_pcOutputDepth );
2156  }
2157
2158  m_pcTempImage = new PelImage( m_auiInputResolution[0],m_auiInputResolution[1],1,2);
2159
2160  // SubPelShiftLUT
2161  if (iInterpolationMode == eRenInt8Tap)
2162  {
2163    // SubPel Shift LUT
2164    Int iNumEntries = (1 << ( m_iRelShiftLUTPrec + 1) ) + 1 ;
2165    m_aaiSubPelShift = new Int*[ iNumEntries ];
2166    for (UInt uiEntry = 0; uiEntry < iNumEntries; uiEntry++)
2167    {
2168      m_aaiSubPelShift[uiEntry] = new Int[ iNumEntries ];
2169    }
2170
2171    TRenFilter::setSubPelShiftLUT(m_iRelShiftLUTPrec, m_aaiSubPelShift, -1);
2172  }
2173
2174  // Zheijang temporal filter
2175  m_aiBlkMoving    = new Int[ ( m_auiInputResolution[0] >> 2 ) + 4 ];
2176  m_aiBlkMoving[0] = 0;
2177  m_aiBlkMoving[1] = 0;
2178  m_aiBlkMoving[ ( m_auiInputResolution[0] >> 2 ) + 2 ] = 0;
2179  m_aiBlkMoving[ ( m_auiInputResolution[0] >> 2 ) + 3 ] = 0;
2180}
2181
2182
2183TRenTop::~TRenTop()
2184{
2185  if ( m_ppdShiftLUTRightMirror != NULL )
2186  {
2187    delete[] m_ppdShiftLUTRightMirror[0];
2188    delete[] m_ppdShiftLUTRightMirror[1];
2189    delete[] m_ppdShiftLUTRightMirror;
2190  };
2191
2192  if ( m_ppiShiftLUTRightMirror != NULL )
2193  {
2194    delete[] m_ppiShiftLUTRightMirror[0];
2195    delete[] m_ppiShiftLUTRightMirror[1];
2196    delete[] m_ppiShiftLUTRightMirror;
2197  };
2198
2199  if (m_piInvZLUTLeft      != NULL ) delete[] m_piInvZLUTLeft   ;
2200  if (m_piInvZLUTLeft      != NULL ) delete[] m_piInvZLUTRight  ;
2201
2202  if (m_pcLeftInputImage   != NULL ) delete m_pcLeftInputImage  ;
2203  if (m_pcLeftInputDepth   != NULL ) delete m_pcLeftInputDepth  ;
2204  if (m_pcLeftOutputImage  != NULL ) delete m_pcLeftOutputImage ;
2205  if (m_pcLeftOutputDepth  != NULL ) delete m_pcLeftOutputDepth ;
2206  if (m_pcLeftFilled       != NULL ) delete m_pcLeftFilled      ;
2207
2208  if (m_pcRightInputImage  != NULL ) delete m_pcRightInputImage ;
2209  if (m_pcRightInputDepth  != NULL ) delete m_pcRightInputDepth ;
2210  if (m_pcRightOutputImage != NULL ) delete m_pcRightOutputImage;
2211  if (m_pcRightOutputDepth != NULL ) delete m_pcRightOutputDepth;
2212  if (m_pcRightFilled      != NULL ) delete m_pcRightFilled     ;
2213
2214  if (m_pcOutputImage      != NULL ) delete m_pcOutputImage     ;
2215  if (m_pcOutputDepth      != NULL ) delete m_pcOutputDepth     ;
2216
2217  if (m_pcInputImage       != NULL ) delete m_pcInputImage      ;
2218  if (m_pcInputDepth       != NULL ) delete m_pcInputDepth      ;
2219  if (m_pcFilled           != NULL ) delete m_pcFilled          ;
2220
2221  if (m_pcTempImage        != NULL ) delete m_pcTempImage       ;
2222
2223  // SubPel LUT
2224  if ( m_aaiSubPelShift != NULL)
2225  {
2226    Int iNumEntries = (1 << ( m_iRelShiftLUTPrec + 1) ) + 1;
2227    for (UInt uiEntry = 0; uiEntry < iNumEntries; uiEntry++)
2228    {
2229      delete[] m_aaiSubPelShift[uiEntry];
2230    }
2231    delete[] m_aaiSubPelShift;
2232  }
2233
2234  // Zheijang temporal filter
2235  if(m_aiBlkMoving         != NULL ) delete[] m_aiBlkMoving;
2236}
2237#endif // H_3D
2238
Note: See TracBrowser for help on using the repository browser.