source: 3DVCSoftware/branches/HTM-3.1-Qualcomm/source/Lib/TLibRenderer/TRenTop.cpp @ 89

Last change on this file since 89 was 81, checked in by tech, 12 years ago

Bug fixes:

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