source: 3DVCSoftware/trunk/source/Lib/TAppCommon/TAppComCamPara.cpp

Last change on this file was 1405, checked in by tech, 8 years ago

Merged HTM-16.1-dev@1404.

File size: 53.1 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-2016, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35
36
37// Include files
38#include "TAppComCamPara.h"
39
40
41#include <stdlib.h>
42#include <math.h>
43#include <errno.h>
44#include <assert.h>
45#include <vector>
46#include <iostream>
47#include <fstream>
48#include <algorithm>
49#include <functional>
50#include <string>
51#if NH_3D_VSO || NH_3D
52
53
54Void
55TAppComCamPara::xCreateLUTs( UInt uiNumberSourceViews, UInt uiNumberTargetViews, Double****& radLUT, Int****& raiLUT, Double***& radShiftParams, Int64***& raiShiftParams )
56{
57  AOF( m_uiBitDepthForLUT == 8 );
58  AOF( radShiftParams == NULL && raiShiftParams == NULL && radLUT == NULL && raiLUT == NULL );
59
60  uiNumberSourceViews = std::max( (UInt) 1, uiNumberSourceViews );
61  uiNumberTargetViews = std::max( (UInt) 1, uiNumberTargetViews );
62
63  radShiftParams = new Double** [ uiNumberSourceViews ];
64  raiShiftParams = new Int64 ** [ uiNumberSourceViews ];
65  radLUT         = new Double***[ uiNumberSourceViews ];
66  raiLUT         = new Int   ***[ uiNumberSourceViews ];
67
68  for( UInt uiSourceView = 0; uiSourceView < uiNumberSourceViews; uiSourceView++ )
69  {
70    radShiftParams[ uiSourceView ] = new Double* [ uiNumberTargetViews ];
71    raiShiftParams[ uiSourceView ] = new Int64 * [ uiNumberTargetViews ];
72    radLUT        [ uiSourceView ] = new Double**[ uiNumberTargetViews ];
73    raiLUT        [ uiSourceView ] = new Int   **[ uiNumberTargetViews ];
74
75    for( UInt uiTargetView = 0; uiTargetView < uiNumberTargetViews; uiTargetView++ )
76    {
77      radShiftParams[ uiSourceView ][ uiTargetView ]      = new Double [ 2 ];
78      raiShiftParams[ uiSourceView ][ uiTargetView ]      = new Int64  [ 2 ];
79
80      radLUT        [ uiSourceView ][ uiTargetView ]      = new Double*[ 2 ];
81      radLUT        [ uiSourceView ][ uiTargetView ][ 0 ] = new Double [ 257 ];
82      radLUT        [ uiSourceView ][ uiTargetView ][ 1 ] = new Double [ 257 ];
83
84      raiLUT        [ uiSourceView ][ uiTargetView ]      = new Int*   [ 2 ];
85      raiLUT        [ uiSourceView ][ uiTargetView ][ 0 ] = new Int    [ 257 ];
86      raiLUT        [ uiSourceView ][ uiTargetView ][ 1 ] = new Int    [ 257 ];
87    }
88  }
89}
90
91Void
92TAppComCamPara::xCreate2dArray( UInt uiNum1Ids, UInt uiNum2Ids, Int**& raaiArray )
93{
94  AOT( raaiArray || uiNum1Ids == 0 || uiNum2Ids == 0 );
95  raaiArray = new Int* [ uiNum1Ids ];
96  for( UInt uiId1 = 0; uiId1 < uiNum1Ids; uiId1++ )
97  {
98    raaiArray[ uiId1 ] = new Int [ uiNum2Ids ];
99  }
100}
101
102
103Void
104TAppComCamPara::xInit2dArray( UInt uiNum1Ids, UInt uiNum2Ids, Int**& raaiArray, Int iValue )
105{
106  for( UInt uiId1 = 0; uiId1 < uiNum1Ids; uiId1++ )
107  {
108    for( UInt uiId2 = 0; uiId2 < uiNum2Ids; uiId2++ )
109    {
110      raaiArray[ uiId1 ][ uiId2 ] = iValue;
111    }
112  }
113}
114
115
116Void
117TAppComCamPara::convertNumberString( TChar* pchViewNumberString, std::vector<Int>& raiViewNumbers, Double dViewNumPrec )
118{
119  Bool bStringIsRange = false;
120  Int  iIdx           = 0;
121  std::vector<Double> adViewNumbers;
122
123  while( pchViewNumberString != 0 && pchViewNumberString[ iIdx ] != 0 )
124  {
125    if( pchViewNumberString[ iIdx ] == ':' )
126    {
127      bStringIsRange              = true;
128      pchViewNumberString[ iIdx ] = ' ';
129    }
130    iIdx++;
131  }
132
133  TChar* pcNextStart = pchViewNumberString;
134  TChar* pcEnd       = pcNextStart + iIdx;
135  TChar* pcOldStart  = 0;
136
137  while( pcNextStart < pcEnd )
138  {
139    errno = 0;
140    adViewNumbers.push_back( ( strtod( pcNextStart, &pcNextStart ) ) );
141
142    if( errno == ERANGE || pcNextStart == pcOldStart )
143    {
144      std::cerr << "Error Parsing View Number String: `" << pchViewNumberString << "'" << std::endl;
145      AOT(true);
146      exit( EXIT_FAILURE );
147    };
148
149    while( pcNextStart < pcEnd && ( *pcNextStart == ' ' || *pcNextStart == '\t' || *pcNextStart == '\r' ) ) pcNextStart++;
150
151    pcOldStart = pcNextStart;
152  }
153
154  if( bStringIsRange )
155  {
156    if( adViewNumbers.size() != 3 )
157    {
158      std::cerr << "Error Parsing SynthViewNumbers: `" << pchViewNumberString << "'" << std::endl;
159      AOT(true);
160      exit( EXIT_FAILURE );
161    }
162
163    Double dRangeBegin = adViewNumbers[0];
164    Double dRangeStep  = adViewNumbers[1];
165    Double dRangeEnd   = adViewNumbers[2];
166
167    if( ( ( dRangeEnd - dRangeBegin > 0 ) != ( dRangeStep > 0 ) ) || dRangeStep == 0 )
168    {
169      std::cerr << "Error Parsing SynthViewNumbers: `" << pchViewNumberString << "'" << std::endl;
170      AOT(true);
171      exit( EXIT_FAILURE );
172    }
173
174    raiViewNumbers.clear();
175
176    Double dFac = ( dRangeBegin > dRangeEnd ? -1 : 1 );
177
178    for( Double dViewNumber = dRangeBegin; ( dViewNumber - dRangeEnd ) * dFac <= 0; dViewNumber += dRangeStep )
179    {
180      raiViewNumbers.push_back( (Int)( dViewNumber * dViewNumPrec ) );
181    }
182  }
183  else
184  {
185    for( UInt uiViewNum = 0; uiViewNum < adViewNumbers.size(); uiViewNum++ )
186    {
187      raiViewNumbers.push_back( (Int)( adViewNumbers[ uiViewNum ] * dViewNumPrec ) );
188    }
189  }
190}
191
192
193Void
194TAppComCamPara::xReadCameraParameterFile( TChar* pchCfgFileName )
195{
196  assert( pchCfgFileName != NULL );
197
198  std::ifstream cCfgStream( pchCfgFileName, std::ifstream::in );
199  if( !cCfgStream )
200  {
201    std::cerr << "Failed to open camera parameter file: `" << pchCfgFileName << "'" << std::endl;
202    exit( EXIT_FAILURE );
203  }
204
205  Int iLineNumber = 0;
206  do
207  {
208    std::string cLine;
209    getline( cCfgStream, cLine );
210    iLineNumber++;
211
212    size_t iStart = cLine.find_first_not_of( " \t\n\r" );
213
214    if( iStart == std::string::npos )
215    {
216      continue;
217    }
218
219    if( cLine[iStart] == '#' )
220    {
221      continue;
222    }
223
224    TChar* pcNextStart = (TChar*) cLine.data();
225    TChar* pcEnd = pcNextStart + cLine.length();
226
227    std::vector<Double> caNewLine;
228    caNewLine.clear();
229
230    TChar* pcOldStart = 0;
231    while( pcNextStart < pcEnd )
232    {
233      errno = 0;
234      caNewLine.push_back( strtod( pcNextStart, &pcNextStart ) ) ;
235
236      if( errno == ERANGE || ( pcNextStart == pcOldStart ) )
237      {
238        std::cerr << "Failed reading config file: `" << pchCfgFileName << "' Error parsing double values in Line: " << iLineNumber << ' ' << std::endl;
239        assert( 0 );
240        exit( EXIT_FAILURE );
241      };
242      pcOldStart = pcNextStart;
243
244      while( ( pcNextStart < pcEnd ) && ( *pcNextStart == ' ' || *pcNextStart == '\t' || *pcNextStart == '\r' ) ) pcNextStart++;
245    }
246
247    if ( ( caNewLine.size() != 2 ) && ( caNewLine.size() != 7 ) && ( caNewLine.size() != 6 ) && ( caNewLine.size() != 8 ) )
248    {
249      std::cerr << "Failed reading config file: `" << pchCfgFileName << "'" << std::endl;
250      std::cerr << "Invalid number of entries" << std::endl;
251      AOF(false);
252      exit( EXIT_FAILURE );
253    }
254    m_aadCameraParameters.push_back( caNewLine );
255  }
256  while( cCfgStream );
257}
258
259Void
260TAppComCamPara::xGetCodedCameraData( UInt uiSourceView, UInt uiTargetView, Bool bByIdx,  UInt uiFrame, Int& riScale, Int& riOffset, Int& riPrecision )
261{
262  if( bByIdx )
263  {
264    uiSourceView = m_aiBaseViews[ uiSourceView ];
265    uiTargetView = m_aiBaseViews[ uiTargetView ];
266  }
267
268  Int iFoundLine = -1;
269  for( UInt uiCurViewLine = 0; uiCurViewLine < m_aadCameraParameters.size(); uiCurViewLine++ )
270  {
271    if ( m_aadCameraParameters[uiCurViewLine].size() == 2 )
272      continue;
273
274    if(      ( (Int)( m_aadCameraParameters[ uiCurViewLine ][ 3 ] * m_dViewNumPrec ) == uiSourceView )
275          && ( (Int)( m_aadCameraParameters[ uiCurViewLine ][ 2 ] * m_dViewNumPrec ) == uiTargetView )
276      )
277    {
278      if( ( (UInt)m_aadCameraParameters[ uiCurViewLine ][ 0 ] <= uiFrame ) && ( (UInt)m_aadCameraParameters[ uiCurViewLine ][ 1 ] >= uiFrame ) )
279      {
280        if( iFoundLine != -1 )
281        {
282          std::cerr << "Error CameraParameters for SourceView " << (Double) uiSourceView / m_dViewNumPrec << " and Target View " << (Double) uiTargetView / m_dViewNumPrec << " and Frame " << uiFrame << " given multiple times."  << std::endl;
283          AOT(true);
284          exit( EXIT_FAILURE );
285        }
286        else
287        {
288          iFoundLine = uiCurViewLine;
289        }
290      }
291    }
292  }
293
294  if ( iFoundLine == -1 )
295  {
296    std::cerr << "Error CameraParameters for SourceView " << (Double) uiSourceView / m_dViewNumPrec << " and Target View " << (Double) uiTargetView / m_dViewNumPrec << " and Frame " << uiFrame << " not found."  << std::endl;
297    AOT(true);
298    exit( EXIT_FAILURE );
299  }
300
301  riScale     = (Int)( m_aadCameraParameters[ iFoundLine ][ 4 ] );
302  riOffset    = (Int)( m_aadCameraParameters[ iFoundLine ][ 5 ] );
303  riPrecision = (Int)( m_aadCameraParameters[ iFoundLine ][ 6 ] );
304}
305
306Bool
307TAppComCamPara::xGetCameraDataRow( Int iView, UInt uiFrame, UInt& ruiFoundLine )
308{
309  ruiFoundLine = -1;
310  for( UInt uiCurViewLine = 0; uiCurViewLine < m_aadCameraParameters.size(); uiCurViewLine++ )
311  {
312    if( (Int)( m_aadCameraParameters[ uiCurViewLine ][ 0 ] * m_dViewNumPrec ) == iView )
313    {
314      if( ( (UInt)m_aadCameraParameters[ uiCurViewLine ][ 1 ] <= uiFrame ) && ( (UInt)m_aadCameraParameters[ uiCurViewLine ][ 2 ] >= uiFrame ) )
315      {
316        if( ruiFoundLine != -1 )
317        {
318          std::cerr << "Error CameraParameters for View " << (Double) iView / m_dViewNumPrec << " and Frame " << uiFrame << " given multiple times."  << std::endl;
319          exit( EXIT_FAILURE );
320        }
321        else
322        {
323          ruiFoundLine = uiCurViewLine;
324        }
325      }
326    }
327  }
328  return ( ruiFoundLine == -1 );
329}
330
331
332Void
333TAppComCamPara::xGetSortedViewList( const std::vector<Int>& raiViews, std::vector<Int>& raiSortedViews, std::vector<Int>& raiId2SortedId, std::vector<Int>& raiSortedId2Id )
334{
335  AOF( raiViews.size() > 0 );
336  Int iNumViews   = (Int)raiViews.size();
337  raiId2SortedId  = std::vector<Int>( raiViews.size(), -1 );
338  raiSortedId2Id.clear();
339  raiSortedViews.clear();
340  for( Int iSortId = 0; iSortId < iNumViews; iSortId++ )
341  {
342    Int  iLeftMostBaseId = -1;
343    for( Int iBaseId = 0; iLeftMostBaseId == -1 && iBaseId < iNumViews; iBaseId++ )
344    {
345      if( raiId2SortedId[ iBaseId ] == -1 )
346      {
347        UInt   uiFoundLine   = -1;
348        xGetCameraDataRow( raiViews[ iBaseId ], 0, uiFoundLine );
349        AOT(   uiFoundLine  == -1 ); // something wrong
350        Double dXPos         = m_aadCameraParameters[ uiFoundLine ][ 4 ];
351        Double dZNear        = m_aadCameraParameters[ uiFoundLine ][ 6 ];
352        Double dZFar         = m_aadCameraParameters[ uiFoundLine ][ 7 ];
353        Double dSign         = ( dZFar > 0 ? 1.0 : -1.0 );
354        Bool   bLeftMost     = true;
355        AOF( dZNear * dZFar  > 0.0 ); // otherwise, z parameters are not correct
356
357        for( Int iTestBaseId = 0; bLeftMost && iTestBaseId < iNumViews; iTestBaseId++ )
358        {
359          if( iTestBaseId != iBaseId && raiId2SortedId[ iTestBaseId ] == -1 )
360          {
361            UInt   uiFoundLineTest  = -1;
362            xGetCameraDataRow( raiViews[ iTestBaseId ], 0, uiFoundLineTest );
363            AOT(   uiFoundLineTest == -1 ); // something wrong
364            Double dXPosTest        = m_aadCameraParameters[ uiFoundLineTest ][ 4 ];
365            Double dZNearTest       = m_aadCameraParameters[ uiFoundLineTest ][ 6 ];
366            Double dZFarTest        = m_aadCameraParameters[ uiFoundLineTest ][ 7 ];
367            AOF( dZNearTest * dZFarTest > 0.0 ); // otherwise, z parameters are not correct
368            AOF( dZNearTest * dSign     > 0.0 ); // otherwise, z parameters are not consistent
369            Double dDeltaXPos       = dSign * ( dXPosTest - dXPos );
370            bLeftMost               = ( bLeftMost && dDeltaXPos > 0.0 );
371          }
372        }
373        if( bLeftMost )
374        {
375          iLeftMostBaseId = iBaseId;
376        }
377      }
378    }
379    AOT( iLeftMostBaseId == -1 ); // something wrong
380    raiId2SortedId[ iLeftMostBaseId ] = iSortId;
381    raiSortedId2Id.push_back( iLeftMostBaseId );
382    raiSortedViews.push_back( raiViews[ iLeftMostBaseId ] );
383  }
384
385  // sanity check
386  if( iNumViews > 2 )
387  {
388    Int   iDeltaView  = gSign( raiSortedViews[ 1 ] - raiSortedViews[ 0 ] );
389    Bool  bOutOfOrder = false;
390    for(  Int  iSIdx  = 2; iSIdx < iNumViews; iSIdx++ )
391    {
392      bOutOfOrder = ( bOutOfOrder || iDeltaView * gSign( raiSortedViews[ iSIdx ] - raiSortedViews[ iSIdx - 1 ] ) < 0 );
393    }
394    if( bOutOfOrder )
395    {
396      std::cerr << "ERROR: View numbering must be strictly increasing or decreasing from left to right" << std::endl;
397      exit(EXIT_FAILURE);
398    }
399  }
400}
401
402
403
404
405Bool
406TAppComCamPara::xGetCamParsChangeFlag()
407{
408  Bool bChangeDetected = false;
409  for( Int iBaseViewId = 0; !bChangeDetected && iBaseViewId < m_iNumberOfBaseViews; iBaseViewId++ )
410  {
411    if ( m_bSetupFromCoded )
412    {
413      for( Int iTargetViewId = 0; !bChangeDetected && iTargetViewId < m_iNumberOfBaseViews; iTargetViewId++ )
414      {
415        Int iTargetView = m_aiBaseViews[iTargetViewId];
416        Int iSourceView = m_aiBaseViews[iBaseViewId  ];
417
418        Int iS1 ,iSX;
419        Int iO1 ,iOX;
420        Int iP1 ,iPX;
421
422        if ( iSourceView == iTargetView )
423          continue;
424
425        xGetCodedCameraData( iSourceView, iTargetView, false, 0, iS1, iO1, iP1 );
426        for( UInt uiFrameId = m_uiFirstFrameId + 1; !bChangeDetected && uiFrameId <= m_uiLastFrameId; uiFrameId++ )
427        {
428          xGetCodedCameraData( iSourceView, iTargetView, false, uiFrameId, iSX, iOX, iPX );
429
430          if( iS1 != iSX || iO1 != iOX || iP1 != iPX )
431          {
432            bChangeDetected = true;
433          }
434        }
435      }
436    }
437    else
438    {
439      Int     iBaseView  = m_aiBaseViews[ iBaseViewId ];
440      Double  dFL1, dFLX;
441      Double  dCP1, dCPX;
442      Double  dCS1, dCSX;
443      Double  dZN1, dZNX;
444      Double  dZF1, dZFX;
445      Bool    bInterpolated;
446      xGetGeometryData( iBaseView, m_uiFirstFrameId, dFL1, dCP1, dCS1, bInterpolated );  AOT( bInterpolated );
447      xGetZNearZFar   ( iBaseView, m_uiFirstFrameId, dZN1, dZF1 );
448
449      for( UInt uiFrameId = m_uiFirstFrameId + 1; !bChangeDetected && uiFrameId <= m_uiLastFrameId; uiFrameId++ )
450      {
451        xGetGeometryData( iBaseView, uiFrameId, dFLX, dCPX, dCSX, bInterpolated );  AOT( bInterpolated );
452        xGetZNearZFar   ( iBaseView, uiFrameId, dZNX, dZFX );
453
454        if( dFL1 != dFLX || dCP1 != dCPX || dCS1 != dCSX || dZN1 != dZNX || dZF1 != dZFX )
455        {
456          bChangeDetected = true;
457        }
458      }
459    }
460  }
461  return bChangeDetected;
462}
463
464Int
465TAppComCamPara::xGetViewId( std::vector<Int> aiViewList, Int iBaseView )
466{
467  Int  iViewId = -1;
468  for( Int iId = 0; iId < (Int)aiViewList.size(); iId++ )
469  {
470    if( aiViewList[ iId ] == iBaseView )
471    {
472      iViewId = iId;
473      break;
474    }
475  }
476  AOT(   iViewId == -1 );
477  return iViewId;
478}
479
480Int
481TAppComCamPara::xGetBaseViewId( Int iBaseView )
482{
483  return xGetViewId( m_aiBaseViews, iBaseView );
484}
485
486
487Bool
488TAppComCamPara::xGetLeftRightView( Int iView, std::vector<Int> aiSortedViews, Int& riLeftView, Int& riRightView, Int& riLeftSortedViewIdx, Int& riRightSortedViewIdx )
489{
490  Bool bFoundLRView  = false;
491  Int  iLeftView     = -1;
492  Int  iRightView    = -1;
493  Int  iLeftViewIdx  = -1;
494  Int  iRightViewIdx = -1;
495  Bool bDecencdingVN = ( aiSortedViews.size() >= 2 && aiSortedViews[ 0 ] > aiSortedViews[ 1 ] );
496  Int  iFactor       = ( bDecencdingVN ? -1 : 1 );
497
498  for( Int iIdx = -1; iIdx < (Int)aiSortedViews.size(); iIdx++ )
499  {
500    if( iIdx == -1 )
501    {
502      if( ( aiSortedViews[ iIdx + 1 ] - iView ) * iFactor > 0  )
503      {
504        bFoundLRView  = false;
505        iLeftView     = -1;
506        iRightView    = aiSortedViews[ iIdx + 1 ];
507        iLeftViewIdx  = -1;
508        iRightViewIdx = iIdx + 1;
509        break;
510      }
511    }
512    else if ( iIdx == (Int)aiSortedViews.size() - 1 )
513    {
514      if( ( aiSortedViews[ iIdx ] - iView ) * iFactor < 0  )
515      {
516        bFoundLRView  = false;
517        iLeftView     = aiSortedViews[ iIdx ];
518        iRightView    = -1;
519        iLeftViewIdx  = iIdx;
520        iRightViewIdx = -1;
521        break;
522      }
523    }
524    else
525    {
526      if( ( ( aiSortedViews[ iIdx ] - iView ) * iFactor <= 0 ) && ( ( aiSortedViews[ iIdx + 1 ] - iView ) * iFactor >= 0 ) )
527      {
528        bFoundLRView  = true;
529        iLeftView     = aiSortedViews[ iIdx ];
530        iRightView    = aiSortedViews[ iIdx + 1 ];
531        iLeftViewIdx  = iIdx;
532        iRightViewIdx = iIdx + 1;
533        break;
534      }
535    }
536  }
537
538  if ( ( iView == iLeftView ) || ( iView == iRightView ) )
539  {
540    iLeftViewIdx  = ( iView == iLeftView ) ? iLeftViewIdx : iRightViewIdx;
541    iRightViewIdx = iLeftViewIdx;
542    iLeftView     = iView;
543    iRightView    = iView;
544    bFoundLRView  = false;
545  }
546
547  riLeftView           = iLeftView;
548  riRightView          = iRightView;
549  riLeftSortedViewIdx  = iLeftViewIdx;
550  riRightSortedViewIdx = iRightViewIdx;
551
552  return bFoundLRView;
553}
554
555
556Void
557TAppComCamPara::xGetPrevAndNextBaseView( Int iSourceViewNum, Int iTargetViewNum, Int& riPrevBaseViewNum, Int& riNextBaseViewNum )
558{
559  Int iLeftView;
560  Int iRightView;
561  Int iDummy;
562  xGetLeftRightView( iTargetViewNum, m_aiSortedBaseViews, iLeftView, iRightView, iDummy, iDummy );
563
564  if( iLeftView == iRightView )
565  {
566    riPrevBaseViewNum = iLeftView;
567    riNextBaseViewNum = iLeftView;
568  }
569  else
570  {
571    Bool bDecencdingVN   = ( m_aiSortedBaseViews.size() >= 2 && m_aiSortedBaseViews[ 0 ] > m_aiSortedBaseViews[ 1 ] );
572    Bool bNextViewIsLeft = ( bDecencdingVN ? ( iSourceViewNum < iTargetViewNum ) : ( iSourceViewNum > iTargetViewNum ) );
573    if ( bNextViewIsLeft )
574    {
575      riPrevBaseViewNum = iRightView;
576      riNextBaseViewNum = iLeftView;
577    }
578    else
579    {
580      riPrevBaseViewNum = iLeftView;
581      riNextBaseViewNum = iRightView;
582    }
583  }
584}
585
586
587Void
588TAppComCamPara::xGetZNearZFar( Int iView, UInt uiFrame, Double& rdZNear, Double& rdZFar )
589{
590  UInt uiFoundLine = -1;
591  if( !xGetCameraDataRow( iView, uiFrame, uiFoundLine ) || !( m_aadCameraParameters[ uiFoundLine ].size() < 8 ) )
592  {
593    rdZNear = m_aadCameraParameters[ uiFoundLine ][ 6 ];
594    rdZFar  = m_aadCameraParameters[ uiFoundLine ][ 7 ];
595  }
596  else
597  {
598    std::cerr << "No ZNear or no ZFar for View " << (Double)iView / m_dViewNumPrec << " and Frame " << uiFrame << " given in CameraParameterFile" << std::endl;
599    exit( EXIT_FAILURE );
600  }
601}
602
603Void
604TAppComCamPara::xGetGeometryData( Int iView, UInt uiFrame, Double& rdFocalLength, Double& rdPosition, Double& rdCameraShift, Bool& rbInterpolated )
605{
606  UInt uiFoundLine = -1;
607  if ( !xGetCameraDataRow( iView, uiFrame, uiFoundLine ) && xIsIn( m_aiSortedBaseViews, iView ))
608  {
609    AOT( m_aadCameraParameters[ uiFoundLine ].size() < 6 );
610    rbInterpolated = false;
611    rdFocalLength =  m_aadCameraParameters[ uiFoundLine ][ 3 ];
612    rdPosition    =  m_aadCameraParameters[ uiFoundLine ][ 4 ];
613    rdCameraShift =  m_aadCameraParameters[ uiFoundLine ][ 5 ];
614  }
615  else
616  {
617    UInt uiLeftViewLine;
618    UInt uiRightViewLine;
619    Int  iLeftView;
620    Int  iRightView;
621    Int  iDummy;
622
623    if( !xGetLeftRightView( iView, m_aiSortedBaseViews, iLeftView, iRightView, iDummy, iDummy ) ||
624         xGetCameraDataRow( iLeftView,  uiFrame, uiLeftViewLine  )                             ||
625         xGetCameraDataRow( iRightView, uiFrame, uiRightViewLine )
626      )
627    {
628      std::cerr << "No left or no right base view next to view " << (Double)iView / m_dViewNumPrec << " for Frame " << uiFrame << " given in CameraParameterFile" << std::endl;
629      AOT(true);
630      exit( EXIT_FAILURE );
631    }
632    AOT( m_aadCameraParameters[ uiLeftViewLine  ].size() < 6 );
633    AOT( m_aadCameraParameters[ uiRightViewLine ].size() < 6 );
634
635    // Linear Interpolation
636    Double dFactor = ( (Double)( iView - iLeftView ) ) / ( (Double)( iRightView - iLeftView ) );
637    rdFocalLength  = m_aadCameraParameters[ uiLeftViewLine ][ 3 ] + dFactor * ( m_aadCameraParameters[ uiRightViewLine ][ 3 ] - m_aadCameraParameters[ uiLeftViewLine ][ 3 ] );
638    rdPosition     = m_aadCameraParameters[ uiLeftViewLine ][ 4 ] + dFactor * ( m_aadCameraParameters[ uiRightViewLine ][ 4 ] - m_aadCameraParameters[ uiLeftViewLine ][ 4 ] );
639    rdCameraShift  = m_aadCameraParameters[ uiLeftViewLine ][ 5 ] + dFactor * ( m_aadCameraParameters[ uiRightViewLine ][ 5 ] - m_aadCameraParameters[ uiLeftViewLine ][ 5 ] );
640    rbInterpolated = true;
641  }
642}
643
644Bool
645TAppComCamPara::xGetShiftParameterReal( UInt uiSourceView, UInt uiTargetView, UInt uiFrame, Bool bExternal, Bool bByIdx, Double& rdScale, Double& rdOffset )
646{
647  AOT( m_bSetupFromCoded );
648
649  Bool   bInterpolatedSource;
650  Double dMinDepthSource;
651  Double dMaxDepthSource;
652  Double dFocalLengthSource;
653  Double dPositionSource;
654  Double dIntersectionSource;
655
656  Bool   bInterpolatedTarget;
657  Double dPositionTarget;
658  Double dIntersectionTarget;
659  Double dFocalLengthTarget;
660
661  Int    iTargetViewNum;
662  Int    iSourceViewNum;
663
664  if( bByIdx )
665  {
666    iSourceViewNum = m_aiBaseViews[ uiSourceView ];
667    iTargetViewNum = ( bExternal ? m_aiSynthViews[ uiTargetView ] : m_aiBaseViews[ uiTargetView ] );
668  }
669  else
670  {
671    iSourceViewNum = (Int) uiSourceView;
672    iTargetViewNum = (Int) uiTargetView;
673  }
674
675  xGetGeometryData( iSourceViewNum, uiFrame, dFocalLengthSource, dPositionSource, dIntersectionSource, bInterpolatedSource );
676  xGetZNearZFar   ( iSourceViewNum, uiFrame, dMinDepthSource,    dMaxDepthSource );
677  xGetGeometryData( iTargetViewNum, uiFrame, dFocalLengthTarget, dPositionTarget, dIntersectionTarget, bInterpolatedTarget );
678
679  Double dFactor = dFocalLengthSource * ( dPositionTarget - dPositionSource );
680  rdScale        = dFactor * ( 1.0 / dMinDepthSource - 1.0 / dMaxDepthSource ) / (Double)( ( 1 << m_uiInputBitDepth ) - 1 );
681  rdOffset       = dFactor / dMaxDepthSource - dIntersectionTarget + dIntersectionSource;
682
683  return ( bInterpolatedSource || bInterpolatedTarget );
684}
685
686
687Void
688TAppComCamPara::xGetShiftParameterCoded( UInt uiSourceView, UInt uiTargetView, UInt uiFrame, Bool bByIdx, Int& riScale, Int& riOffset )
689{
690  if ( m_bSetupFromCoded )
691  {
692    if ( uiSourceView == uiTargetView )
693    {
694      riScale  = 0;
695      riOffset = 0;
696      return;
697    }
698    Int iCamParsCodedPrecision;
699    xGetCodedCameraData( uiSourceView, uiTargetView,  bByIdx, uiFrame, riScale, riOffset, iCamParsCodedPrecision );
700
701    if ( m_bCamParsCodedPrecSet )
702    {
703      AOT( m_uiCamParsCodedPrecision != (UInt) iCamParsCodedPrecision );
704    }
705    else
706    {
707      m_uiCamParsCodedPrecision = (UInt) iCamParsCodedPrecision;
708      m_bCamParsCodedPrecSet    = true;
709    }
710  }
711  else
712  {
713    Double  dScale, dOffset;
714    Bool    bInterpolated = xGetShiftParameterReal( uiSourceView, uiTargetView, uiFrame, false, bByIdx, dScale, dOffset );
715    AOT(    bInterpolated ); // must be base view
716
717    Double  dMultOffset   = (Double)( 1 << ( m_uiCamParsCodedPrecision + 1 ) );
718    Double  dMultScale    = (Double)( 1 << ( m_uiCamParsCodedPrecision + 1 + m_uiInputBitDepth ) );
719    riOffset              = (Int)floor( dMultOffset * dOffset + .5 );
720    riScale               = (Int)floor( dMultScale  * dScale  + .5 );
721  }
722}
723
724
725Void
726TAppComCamPara::xGetShiftParameterInt( UInt uiSourceView, UInt uiTargetView, UInt uiFrame, Bool bExternal, Bool bByIdx, Int64& riScale, Int64& riOffset )
727{
728  Int    iTargetViewNum;
729  Int    iSourceViewNum;
730  Int    iPrevBaseViewNum;
731  Int    iNextBaseViewNum;
732  Int    iTargetViewRelNum;
733
734  if( bByIdx )
735  {
736
737    iSourceViewNum = m_aiBaseViews[ uiSourceView ];
738
739    if ( bExternal )
740    {
741      iTargetViewNum    = m_aiSynthViews      [ uiTargetView ];
742      iTargetViewRelNum = m_aiRelSynthViewsNum[ uiTargetView ];
743    }
744    else
745    {
746      iTargetViewNum    = m_aiBaseViews       [ uiTargetView ];
747      iTargetViewRelNum = m_aiBaseId2SortedId [ uiTargetView ] * ((Int) m_dViewNumPrec );
748    }
749  }
750  else
751  {
752    iSourceViewNum = (Int) uiSourceView;
753    iTargetViewNum = (Int) uiTargetView;
754
755    if ( bExternal )
756    {
757      iTargetViewRelNum = m_aiRelSynthViewsNum[ xGetViewId( m_aiSynthViews, (Int) uiTargetView )];
758    }
759    else
760    {
761      iTargetViewRelNum = m_aiBaseId2SortedId[ xGetBaseViewId( uiTargetView) ] * ((Int) m_dViewNumPrec );
762    }
763  }
764  xGetPrevAndNextBaseView( iSourceViewNum, iTargetViewNum, iPrevBaseViewNum, iNextBaseViewNum );
765  AOT( iPrevBaseViewNum == -1 ); // should not happen
766  AOT( iNextBaseViewNum == -1 ); // should not happen
767
768  Int iSrcId    = xGetBaseViewId( iSourceViewNum   );
769  Int iPrevId   = xGetBaseViewId( iPrevBaseViewNum );
770  Int iNextId   = xGetBaseViewId( iNextBaseViewNum );
771  AOF( m_aaiScaleAndOffsetSet[ iSrcId ][ iPrevId ] ); // coded scale and offset must be set
772  AOF( m_aaiScaleAndOffsetSet[ iSrcId ][ iNextId ] ); // coded scale and offset must be set
773
774  Int iNextBaseViewRelNum = m_aiBaseId2SortedId[ iNextId ] * ((Int) m_dViewNumPrec );
775  Int iPrevBaseViewRelNum = m_aiBaseId2SortedId[ iPrevId ] * ((Int) m_dViewNumPrec );
776
777  Int64 iPrevScale  = (Int64)m_aaiCodedScale [ iSrcId ][ iPrevId ];
778  Int64 iNextScale  = (Int64)m_aaiCodedScale [ iSrcId ][ iNextId ];
779  Int64 iPrevOffset = (Int64)m_aaiCodedOffset[ iSrcId ][ iPrevId ] << m_uiBitDepthForLUT;
780  Int64 iNextOffset = (Int64)m_aaiCodedOffset[ iSrcId ][ iNextId ] << m_uiBitDepthForLUT;
781
782  if( iPrevBaseViewNum == iNextBaseViewNum )
783  {
784    riScale   = iNextScale;
785    riOffset  = iNextOffset;
786  }
787  else
788  {
789    riScale   = Int64( iTargetViewRelNum    - iPrevBaseViewRelNum ) * iNextScale;
790    riScale  += Int64( iNextBaseViewRelNum  - iTargetViewRelNum   ) * iPrevScale;
791    riOffset  = Int64( iTargetViewRelNum   - iPrevBaseViewRelNum ) * iNextOffset;
792    riOffset += Int64( iNextBaseViewRelNum - iTargetViewRelNum   ) * iPrevOffset;
793    Int64 iD  = Int64( iNextBaseViewRelNum - iPrevBaseViewRelNum );
794    Int64 iSA = ( riScale  > 0 ? iD / 2 : -iD / 2 );
795    Int64 iOA = ( riOffset > 0 ? iD / 2 : -iD / 2 );
796    riScale   = ( riScale  + iSA  ) / iD;
797    riOffset  = ( riOffset + iOA  ) / iD;
798  }
799}
800
801
802Void
803TAppComCamPara::xSetCodedScaleOffset( UInt uiFrame )
804{
805  for( UInt uiSourceId = 0; uiSourceId < m_iNumberOfBaseViews; uiSourceId++ )
806  {
807    for( UInt uiTargetId = 0; uiTargetId < m_iNumberOfBaseViews; uiTargetId++ )
808    {
809      Int iScale, iOffset;
810      xGetShiftParameterCoded( uiSourceId, uiTargetId, uiFrame, true, iScale, iOffset );
811      m_aaiCodedScale        [ uiSourceId ][ uiTargetId ] = iScale;
812      m_aaiCodedOffset       [ uiSourceId ][ uiTargetId ] = iOffset;
813      m_aaiScaleAndOffsetSet [ uiSourceId ][ uiTargetId ] = 1;
814    }
815  }
816}
817
818
819Void
820TAppComCamPara::xSetShiftParametersAndLUT( UInt uiNumberSourceViews, UInt uiNumberTargetViews, UInt uiFrame, Bool bExternalReference , Double****& radLUT, Int****& raiLUT, Double***& radShiftParams, Int64***& raiShiftParams )
821{
822  if( uiNumberSourceViews <= 1 || uiNumberTargetViews == 0 )
823  {
824    return;
825  }
826  AOF( radShiftParams != NULL && raiShiftParams != NULL && radLUT != NULL && raiLUT != NULL );
827  AOF( m_uiBitDepthForLUT == 8 );
828
829  Int     iLog2DivLuma   = m_uiBitDepthForLUT + m_uiCamParsCodedPrecision + 1 - m_iLog2Precision;   AOF( iLog2DivLuma > 0 );
830  Int     iLog2DivChroma = iLog2DivLuma + 1;
831
832  Double  dMaxDispDev    = 0.0;
833  Double  dMaxRndDispDvL = 0.0;
834  Double  dMaxRndDispDvC = 0.0;
835
836  for( UInt uiSourceView = 0; uiSourceView < uiNumberSourceViews; uiSourceView++ )
837  {
838    for( UInt uiTargetView = 0; uiTargetView < uiNumberTargetViews; uiTargetView++ )
839    {
840
841      // integer-valued scale and offset
842      Int64 iScale, iOffset;
843      xGetShiftParameterInt ( uiSourceView, uiTargetView, uiFrame, bExternalReference, true, iScale, iOffset );
844      raiShiftParams[ uiSourceView][ uiTargetView ][ 0 ] = iScale;
845      raiShiftParams[ uiSourceView][ uiTargetView ][ 1 ] = iOffset;
846
847      // offsets including rounding offsets
848      Int64 iOffsetLuma   = iOffset + ( ( 1 << iLog2DivLuma   ) >> 1 );
849      Int64 iOffsetChroma = iOffset + ( ( 1 << iLog2DivChroma ) >> 1 );
850
851      // real-valued scale and offset
852      Double dScale, dOffset;
853
854      if ( m_bSetupFromCoded )
855      {
856        dScale  = (Double) iScale  / (( Double ) ( 1 << iLog2DivLuma ));
857        dOffset = (Double) iOffset / (( Double ) ( 1 << iLog2DivLuma ));
858      }
859      else
860      {
861        xGetShiftParameterReal( uiSourceView, uiTargetView, uiFrame, bExternalReference, true, dScale, dOffset );
862      }
863
864      radShiftParams[ uiSourceView][ uiTargetView ][ 0 ] = dScale;
865      radShiftParams[ uiSourceView][ uiTargetView ][ 1 ] = dOffset;
866
867      for( UInt uiDepthValue = 0; uiDepthValue < 256; uiDepthValue++ )
868      {
869        // real-valued look-up tables
870        Double  dShiftLuma      = ( (Double)uiDepthValue * dScale + dOffset ) * Double( 1 << m_iLog2Precision );
871        Double  dShiftChroma    = dShiftLuma / 2;
872        radLUT[ uiSourceView ][ uiTargetView ][ 0 ][ uiDepthValue ] = dShiftLuma;
873        radLUT[ uiSourceView ][ uiTargetView ][ 1 ][ uiDepthValue ] = dShiftChroma;
874
875        // integer-valued look-up tables
876        Int64   iTempScale      = (Int64)uiDepthValue * iScale;
877        Int64   iTestScale      = ( iTempScale + iOffset       );   // for checking accuracy of camera parameters
878        Int64   iShiftLuma      = ( iTempScale + iOffsetLuma   ) >> iLog2DivLuma;
879        Int64   iShiftChroma    = ( iTempScale + iOffsetChroma ) >> iLog2DivChroma;
880        raiLUT[ uiSourceView ][ uiTargetView ][ 0 ][ uiDepthValue ] = (Int)iShiftLuma;
881        raiLUT[ uiSourceView ][ uiTargetView ][ 1 ][ uiDepthValue ] = (Int)iShiftChroma;
882
883        // maximum deviation
884#if NH_3D_REN_MAX_DEV_OUT
885        m_dMaxShiftDeviation = std::max( m_dMaxShiftDeviation, fabs( Double( (Int) iShiftLuma   ) - dShiftLuma   ) / Double( 1 << m_iLog2Precision ) );       
886#endif
887        dMaxDispDev     = std::max( dMaxDispDev,    fabs( Double( (Int) iTestScale   ) - dShiftLuma * Double( 1 << iLog2DivLuma ) ) / Double( 1 << iLog2DivLuma ) );
888        dMaxRndDispDvL  = std::max( dMaxRndDispDvL, fabs( Double( (Int) iShiftLuma   ) - dShiftLuma   ) );
889        dMaxRndDispDvC  = std::max( dMaxRndDispDvC, fabs( Double( (Int) iShiftChroma ) - dShiftChroma ) );
890      }
891
892      radLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 256 ] = radLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 255 ];
893      radLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 256 ] = radLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 255 ];
894      raiLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 256 ] = raiLUT[ uiSourceView ][ uiTargetView ][ 0 ][ 255 ];
895      raiLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 256 ] = raiLUT[ uiSourceView ][ uiTargetView ][ 1 ][ 255 ];
896    }
897  }
898
899  // check maximum deviation
900  Double  dMaxAllowedDispDev    =       Double( 1 << m_iLog2Precision ) / Double( 1 << m_uiCamParsCodedPrecision );       //  counting only the impact of camera parameter rounding
901  Double  dMaxAllowedRndDispDvL = 0.5 + Double( 1 << m_iLog2Precision ) / Double( 1 << m_uiCamParsCodedPrecision );       // final rounding and impact of camera parameter rounding
902  Double  dMaxAllowedRndDispDvC = 0.5 + Double( 1 << m_iLog2Precision ) / Double( 1 << m_uiCamParsCodedPrecision ) / 2.0; // final rounding and impact of camera parameter rounding
903
904  if( ( dMaxDispDev >= dMaxAllowedDispDev || dMaxRndDispDvL >= dMaxAllowedRndDispDvL || dMaxRndDispDvC >= dMaxAllowedRndDispDvC ) && !m_bSetupFromCoded )
905  {
906    std::cout << "Warning: Something wrong with the accuracy of coded camera parameters:" << std::endl;
907    if( dMaxDispDev    >= dMaxAllowedDispDev    )
908    {
909      std::cout << "   max disparity difference is " << dMaxDispDev    << " (allowed: " << dMaxAllowedDispDev    << ")" << std::endl;
910    }
911    if( dMaxRndDispDvL >= dMaxAllowedRndDispDvL )
912    {
913      std::cout << "   max rnd luma   disp diff is " << dMaxRndDispDvL << " (allowed: " << dMaxAllowedRndDispDvL << ")" << std::endl;
914    }
915    if( dMaxRndDispDvC >= dMaxAllowedRndDispDvC )
916    {
917      std::cout << "   max rnd chroma disp diff is " << dMaxRndDispDvC << " (allowed: " << dMaxAllowedRndDispDvC << ")" << std::endl;
918    }
919  }
920}
921
922Void
923TAppComCamPara::xSetShiftParametersAndLUT( UInt uiFrame )
924{
925  xInit2dArray             ( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfBaseViews,  m_aaiScaleAndOffsetSet, 0 );
926  xSetCodedScaleOffset     (                                                          uiFrame );
927  xSetShiftParametersAndLUT( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfBaseViews,  uiFrame, false, m_adBaseViewShiftLUT,  m_aiBaseViewShiftLUT,  m_adBaseViewShiftParameter,  m_aiBaseViewShiftParameter  );
928  xSetShiftParametersAndLUT( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfSynthViews, uiFrame, true,  m_adSynthViewShiftLUT, m_aiSynthViewShiftLUT, m_adSynthViewShiftParameter, m_aiSynthViewShiftParameter );
929};
930
931
932Void
933TAppComCamPara::xGetCameraShifts( UInt uiSourceView, UInt uiTargetView, UInt uiFrame, Double& rdCamPosShift, Double& rdPicPosShift )
934{
935  Double  dDummy, dCamPosSource, dCamPosTarget, dPicPosSource, dPicPosTarget;
936  Bool    bInterpolatedSource, bInterpolatedTarget;
937  Int     iTargetViewNum = m_aiBaseViews[ uiTargetView ];
938  Int     iSourceViewNum = m_aiBaseViews[ uiSourceView ];
939
940  xGetGeometryData( iSourceViewNum, uiFrame, dDummy, dCamPosSource, dPicPosSource, bInterpolatedSource );
941  xGetGeometryData( iTargetViewNum, uiFrame, dDummy, dCamPosTarget, dPicPosTarget, bInterpolatedTarget );
942  AOT( bInterpolatedSource || bInterpolatedTarget );
943
944  rdCamPosShift =  ( dCamPosTarget - dCamPosSource );
945  rdPicPosShift = -( dPicPosTarget - dPicPosSource ); // to be consistent
946}
947
948
949
950
951
952
953TAppComCamPara::TAppComCamPara()
954{
955  m_dViewNumPrec              = VIEW_NUM_PREC;  // fixed
956  m_iLog2Precision            = -1;
957  m_uiInputBitDepth           = 0;
958  m_uiBitDepthForLUT          = 8;              // fixed
959  m_uiFirstFrameId            = 0;
960  m_uiLastFrameId             = 0;
961
962  m_iNumberOfBaseViews        = -1;
963  m_iNumberOfSynthViews       = -1;
964
965  m_uiCamParsCodedPrecision   = 0;
966  m_bCamParsVaryOverTime      = true;
967
968  m_aaiCodedScale             = 0;
969  m_aaiCodedOffset            = 0;
970  m_aaiScaleAndOffsetSet      = 0;
971
972  m_adBaseViewShiftParameter  = 0;
973  m_aiBaseViewShiftParameter  = 0;
974  m_adSynthViewShiftParameter = 0;
975  m_aiSynthViewShiftParameter = 0;
976
977  m_adBaseViewShiftLUT        = 0;
978  m_aiBaseViewShiftLUT        = 0;
979  m_adSynthViewShiftLUT       = 0;
980  m_aiSynthViewShiftLUT       = 0;
981
982  m_bSetupFromCoded           = false;
983  m_bCamParsCodedPrecSet      = false;
984
985#if NH_3D_REN_MAX_DEV_OUT
986  m_dMaxShiftDeviation        = -1; 
987#endif
988
989}
990
991
992TAppComCamPara::~TAppComCamPara()
993{
994  xDeleteArray( m_adBaseViewShiftParameter,  m_iNumberOfBaseViews, m_iNumberOfBaseViews     );
995  xDeleteArray( m_aiBaseViewShiftParameter,  m_iNumberOfBaseViews, m_iNumberOfBaseViews     );
996  xDeleteArray( m_adBaseViewShiftLUT,        m_iNumberOfBaseViews, m_iNumberOfBaseViews,  2 );
997  xDeleteArray( m_aiBaseViewShiftLUT,        m_iNumberOfBaseViews, m_iNumberOfBaseViews,  2 );
998
999  xDeleteArray( m_adSynthViewShiftParameter, m_iNumberOfBaseViews, std::max((Int) 1 ,m_iNumberOfSynthViews));
1000  xDeleteArray( m_aiSynthViewShiftParameter, m_iNumberOfBaseViews, std::max((Int) 1 ,m_iNumberOfSynthViews));
1001  xDeleteArray( m_adSynthViewShiftLUT,       m_iNumberOfBaseViews, std::max((Int) 1 ,m_iNumberOfSynthViews), 2 );
1002  xDeleteArray( m_aiSynthViewShiftLUT,       m_iNumberOfBaseViews, std::max( (Int)1 ,m_iNumberOfSynthViews), 2 );
1003
1004  xDeleteArray( m_aaiCodedScale,             m_iNumberOfBaseViews );
1005  xDeleteArray( m_aaiCodedOffset,            m_iNumberOfBaseViews );
1006  xDeleteArray( m_aaiScaleAndOffsetSet,      m_iNumberOfBaseViews );
1007
1008}
1009
1010Void
1011TAppComCamPara::xSetupBaseViewsFromCoded()
1012{
1013  //===== get and sort views given in camera parameter file and set list of base views and related arrays =====
1014  // get left-right order and coding order from cfg-file
1015  std::vector<Int> aiViewOrderIdx;   // Left Right Order
1016  std::vector<Int> aiViewId ;        // Coding     Order
1017
1018  Int iMinViewOrderIdx = MAX_INT;
1019  for( UInt uiRow = 0; uiRow < m_aadCameraParameters.size(); uiRow++ )
1020  {
1021    if (m_aadCameraParameters[uiRow].size() != 2 )
1022      break;
1023
1024    Int iViewOrderIdx  = (Int)( m_aadCameraParameters[ uiRow ][ 1 ] );
1025    iMinViewOrderIdx   = std::min( iViewOrderIdx, iMinViewOrderIdx );
1026
1027    aiViewOrderIdx     .push_back( iViewOrderIdx );
1028    aiViewId           .push_back( (Int) m_aadCameraParameters[ uiRow ][ 0 ]  );
1029  }
1030
1031  // create base view numbers
1032  AOT( aiViewId.size() != aiViewOrderIdx.size() );
1033  m_iNumberOfBaseViews = (Int) aiViewId.size();
1034  for (Int iCurBaseView = 0; iCurBaseView < m_iNumberOfBaseViews; iCurBaseView++ )
1035  {
1036    aiViewOrderIdx[iCurBaseView] = ( aiViewOrderIdx[iCurBaseView] - iMinViewOrderIdx);
1037    m_aiBaseViews      .push_back(  aiViewOrderIdx[iCurBaseView] * ( (Int) m_dViewNumPrec) );
1038    m_aiBaseId2SortedId.push_back( iCurBaseView );
1039    m_aiBaseSortedId2Id.push_back( iCurBaseView );
1040  }
1041
1042  m_iNumberOfBaseViews = (Int) m_aiBaseViews.size();
1043
1044  std::vector<Int> aiSortedViewOrderIdx = aiViewOrderIdx;
1045
1046  // sort base views according to View Order Idx
1047  m_aiSortedBaseViews = m_aiBaseViews;
1048  for (Int iCurBaseView = 1; iCurBaseView < m_iNumberOfBaseViews; iCurBaseView++ )
1049  {
1050    Int iCurViewOrder = aiSortedViewOrderIdx[iCurBaseView];
1051    for (Int iCurSearchPos = iCurBaseView; iCurSearchPos >= 0; iCurSearchPos-- )
1052    {
1053      if ( iCurViewOrder < aiSortedViewOrderIdx[iCurSearchPos] )
1054      {
1055        Int iTempViewId = m_aiSortedBaseViews[iCurSearchPos];
1056        m_aiSortedBaseViews[iCurSearchPos] = m_aiSortedBaseViews[iCurBaseView];
1057        m_aiSortedBaseViews[iCurBaseView ] = iTempViewId;
1058
1059        Int iTempViewOrderIdx = aiSortedViewOrderIdx[iCurSearchPos];
1060        aiSortedViewOrderIdx[iCurSearchPos] = aiSortedViewOrderIdx[iCurBaseView];
1061        aiSortedViewOrderIdx[iCurBaseView ] = iTempViewOrderIdx;
1062
1063        Int iTempPos = m_aiBaseSortedId2Id[iCurSearchPos];
1064        m_aiBaseSortedId2Id[iCurSearchPos] = m_aiBaseSortedId2Id[iCurBaseView];
1065        m_aiBaseSortedId2Id[iCurBaseView] = iTempPos;
1066        iCurBaseView--;
1067      }
1068    }
1069  }
1070
1071  for (Int iCurBaseView = 0; iCurBaseView < m_iNumberOfBaseViews; iCurBaseView++ )
1072  {
1073    m_aiBaseId2SortedId[m_aiBaseSortedId2Id[iCurBaseView]] = iCurBaseView;
1074  }
1075
1076  m_aiViewsInCfgFile = m_aiSortedBaseViews;
1077
1078  // check
1079  if( m_aiViewsInCfgFile.size() < 2 )
1080  {
1081    std::cerr << "Failed reading camera parameter file" << std::endl;
1082    std::cerr << "At least two views must be given" << std::endl;
1083    AOT(true);
1084    exit( EXIT_FAILURE );
1085  }
1086
1087  // translate coding order to view order
1088  for( UInt uiRow = 0; uiRow < m_aadCameraParameters.size(); uiRow++ )
1089{
1090    if (m_aadCameraParameters[uiRow].size() == 2 )
1091      continue;
1092
1093    m_aadCameraParameters[ uiRow ][ 2 ] = (Double) aiViewOrderIdx[ xGetViewId( aiViewId, (Int) m_aadCameraParameters[ uiRow ][ 2 ] ) ];
1094    m_aadCameraParameters[ uiRow ][ 3 ] = (Double) aiViewOrderIdx[ xGetViewId( aiViewId, (Int) m_aadCameraParameters[ uiRow ][ 3 ] ) ];
1095  }
1096}
1097
1098Void TAppComCamPara::xSetupBaseViews( TChar* pchBaseViewNumbers, UInt uiNumBaseViews )
1099  {
1100    // init list
1101    std::vector<Int> aiViewsInCfg;
1102    for( UInt uiRow = 0; uiRow < m_aadCameraParameters.size(); uiRow++ )
1103    {
1104      aiViewsInCfg.push_back( (Int)( m_aadCameraParameters[ uiRow ][ 0 ] * m_dViewNumPrec ) );
1105    }
1106    // remove duplicated items
1107    std::sort( aiViewsInCfg.begin(), aiViewsInCfg.end() );
1108    std::vector<Int>::iterator cIterNewEnd = std::unique( aiViewsInCfg.begin(), aiViewsInCfg.end() );
1109    aiViewsInCfg.erase( cIterNewEnd, aiViewsInCfg.end() );
1110    // sort (from left to right)
1111    std::vector<Int> aiDummyI2SI, aiDummySI2I;
1112    xGetSortedViewList( aiViewsInCfg, m_aiViewsInCfgFile, aiDummyI2SI, aiDummySI2I );
1113    // check
1114    if( m_aiViewsInCfgFile.size() < 2 )
1115    {
1116      std::cerr << "Failed reading config file" << std::endl;
1117      std::cerr << "At least two views must be given" << std::endl;
1118      exit( EXIT_FAILURE );
1119    }
1120
1121
1122
1123  //===== set list of base views and related arrays =====
1124  if( pchBaseViewNumbers == 0 )
1125  {
1126    std::cerr << "BaseViewCameraNumbers must be given" << std::endl;
1127    exit( EXIT_FAILURE );
1128  };
1129
1130  convertNumberString( pchBaseViewNumbers, m_aiBaseViews, m_dViewNumPrec  );
1131  while( (UInt)m_aiBaseViews.size() > uiNumBaseViews )
1132  {
1133    m_aiBaseViews.pop_back();
1134  }
1135  xGetSortedViewList( m_aiBaseViews, m_aiSortedBaseViews, m_aiBaseId2SortedId, m_aiBaseSortedId2Id );
1136  m_iNumberOfBaseViews = (Int)m_aiBaseViews.size();
1137}
1138
1139
1140Void
1141TAppComCamPara::init( UInt   uiNumBaseViews,
1142                      UInt   uiInputBitDepth,
1143                      UInt   uiCodedCamParsPrecision,
1144                      UInt   uiStartFrameId,
1145                      UInt   uiNumFrames,
1146                      TChar* pchCfgFileName,
1147                      TChar* pchBaseViewNumbers,
1148                      TChar* pchSynthViewNumbers,
1149                      std::vector<Int>* paiSynthViewNumbers,
1150                      Int    iLog2Precision )
1151{
1152  //===== set miscellaneous variables =====
1153  m_uiInputBitDepth         = uiInputBitDepth;
1154  m_uiFirstFrameId          = uiStartFrameId;
1155  m_uiLastFrameId           = uiStartFrameId + uiNumFrames - 1;
1156  m_uiCamParsCodedPrecision = uiCodedCamParsPrecision;
1157  m_iLog2Precision          = iLog2Precision;
1158
1159  xReadCameraParameterFile( pchCfgFileName );
1160
1161  m_bSetupFromCoded         = ( m_aadCameraParameters[ 0 ].size() == 2 );
1162
1163  if ( m_bSetupFromCoded )
1164  {
1165    std::cout << "Detected decoded camera parameter file. Overwriting base view settings from cfg file. " << std::endl;
1166    xSetupBaseViewsFromCoded();
1167  }
1168  else
1169  {
1170    xSetupBaseViews( pchBaseViewNumbers, uiNumBaseViews );
1171  }
1172
1173  //===== set list of external (virtual) views =====
1174  m_aiSynthViews.clear();
1175
1176  if( pchSynthViewNumbers != 0 || paiSynthViewNumbers != 0)
1177  {
1178    std::vector<Int> aiTmpSynthViews;
1179
1180    AOT( ( pchSynthViewNumbers != NULL ) && ( paiSynthViewNumbers != NULL ) );
1181
1182    if ( pchSynthViewNumbers != NULL )
1183    {
1184      convertNumberString( pchSynthViewNumbers, aiTmpSynthViews, m_dViewNumPrec );
1185    }
1186    else
1187    {
1188      aiTmpSynthViews = (*paiSynthViewNumbers);
1189    }
1190
1191    for( UInt uiSId = 0; uiSId < (UInt)aiTmpSynthViews.size(); uiSId++ )
1192    {
1193
1194      Int iViewNumPrec        = (Int) m_dViewNumPrec;
1195      Int iLeftBaseViewIdx    =   aiTmpSynthViews[ uiSId ]                        / iViewNumPrec;
1196      Int iRightBaseViewIdx   = ( aiTmpSynthViews[ uiSId ] + (iViewNumPrec - 1) ) / iViewNumPrec;
1197
1198      if ( iLeftBaseViewIdx < 0 || iRightBaseViewIdx >= m_iNumberOfBaseViews )
1199      {
1200        std::cerr << "SynthViewCameraNumbers must be greater and equal to 0 and smaller than number of base views" << std::endl;
1201        AOT(true);
1202        exit( EXIT_FAILURE );
1203      }
1204
1205      Int64  iLeftBaseViewRelNum = iLeftBaseViewIdx  * iViewNumPrec;
1206      Int64 iRightBaseViewRelNum = iRightBaseViewIdx * iViewNumPrec;
1207
1208      Int64 iDiffBaseViewRelNum  = iRightBaseViewRelNum - iLeftBaseViewRelNum;
1209
1210      Int64 iSynthViewRelNum     = aiTmpSynthViews[ uiSId ];
1211      Int64 iLeftBaseNum         = m_aiSortedBaseViews[ iLeftBaseViewIdx  ];
1212      Int64 iRightBaseNum        = m_aiSortedBaseViews[ iRightBaseViewIdx ];
1213      Int64 iDiffBaseNum         = iRightBaseNum - iLeftBaseNum;
1214      Int64 iSynthViewNum;
1215
1216      if ( iDiffBaseViewRelNum != 0)
1217      {
1218        AOT( (Int) iDiffBaseViewRelNum != iViewNumPrec );
1219        Int iFact = iDiffBaseNum > 0 ? 1 : -1;
1220        iSynthViewNum = iLeftBaseNum + ( iDiffBaseNum * ( iSynthViewRelNum - iLeftBaseViewRelNum ) + (iViewNumPrec >> 1) * iFact ) / ( iViewNumPrec );
1221      }
1222      else
1223      {
1224        iSynthViewNum = iLeftBaseNum;
1225      }
1226
1227      m_aiRelSynthViewsNum.push_back(  aiTmpSynthViews[ uiSId ] );
1228      m_aiSynthViews      .push_back(  (Int) iSynthViewNum  );
1229    }
1230  }
1231  m_iNumberOfSynthViews = (Int)m_aiSynthViews.size();
1232
1233
1234  //===== set derived parameters =====
1235  m_bCamParsVaryOverTime = xGetCamParsChangeFlag();
1236
1237
1238  //===== create arrays =====
1239  xCreateLUTs   ( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfBaseViews,  m_adBaseViewShiftLUT,  m_aiBaseViewShiftLUT,  m_adBaseViewShiftParameter,  m_aiBaseViewShiftParameter  );
1240  xCreateLUTs   ( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfSynthViews, m_adSynthViewShiftLUT, m_aiSynthViewShiftLUT, m_adSynthViewShiftParameter, m_aiSynthViewShiftParameter );
1241  xCreate2dArray( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfBaseViews,  m_aaiCodedScale           );
1242  xCreate2dArray( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfBaseViews,  m_aaiCodedOffset          );
1243  xCreate2dArray( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfBaseViews,  m_aaiScaleAndOffsetSet    );
1244  xInit2dArray  ( (UInt)m_iNumberOfBaseViews, (UInt)m_iNumberOfBaseViews,  m_aaiScaleAndOffsetSet, 0 );
1245
1246  //===== init arrays for first frame =====
1247  xSetShiftParametersAndLUT( m_uiFirstFrameId );
1248}
1249
1250
1251Void
1252TAppComCamPara::check( Bool bCheckViewRange, Bool bCheckFrameRange )
1253{
1254  if( bCheckFrameRange )
1255  {
1256    Double dDummy;
1257
1258    for( UInt uiBaseView = 0; uiBaseView < m_aiBaseViews.size(); uiBaseView++ )
1259    {
1260      if ( m_bSetupFromCoded )
1261      {
1262        for( UInt uiTargetView = 0; uiTargetView < m_aiBaseViews.size(); uiTargetView++ )
1263        {
1264          if ( uiTargetView == uiBaseView )
1265            continue;
1266
1267          for( UInt uiFrame = m_uiFirstFrameId; uiFrame <= m_uiLastFrameId; uiFrame++ )
1268          {
1269            Int iDummy;
1270
1271            xGetCodedCameraData( uiBaseView, uiTargetView, true , uiFrame, iDummy, iDummy, iDummy );
1272          }
1273        }
1274      }
1275      else
1276      {
1277        for( UInt uiFrame = m_uiFirstFrameId; uiFrame <= m_uiLastFrameId; uiFrame++ )
1278        {
1279          Bool bInterpolatedCur;
1280          xGetGeometryData( m_aiBaseViews[ uiBaseView ], uiFrame, dDummy, dDummy, dDummy, bInterpolatedCur );
1281          xGetZNearZFar   ( m_aiBaseViews[ uiBaseView ], uiFrame, dDummy, dDummy );
1282
1283          if( bInterpolatedCur )
1284          {
1285            std::cerr << "Error: CameraParameters for BaseView " << (Double)m_aiBaseViews[ uiBaseView ] / m_dViewNumPrec << " and Frame " << uiFrame << " not defined. "  << std::endl;
1286            exit( EXIT_FAILURE );
1287          }
1288        }
1289      }
1290    }
1291
1292    Bool bIgnoreFirst = true;     
1293    for( UInt uiERView = 0; uiERView < m_aiSynthViews.size() && !m_bSetupFromCoded; uiERView++ )
1294    {
1295      if ( xIsIn(m_aiViewsInCfgFile, m_aiSynthViews[ uiERView ] ) )
1296      {
1297        if ( bIgnoreFirst )
1298        {
1299          std::cout << "Ignoring CameraParameterFile entries for virtual view(s): " ;
1300          //GT: Integer precision virtual view camera parameters are always interpolated from coded views camera parameters.
1301          bIgnoreFirst = false; 
1302        }
1303        std::cout << (Double)m_aiSynthViews[ uiERView ] / m_dViewNumPrec << " " ; 
1304      }
1305    }
1306    if ( !bIgnoreFirst )
1307    {
1308      std::cout << std::endl; 
1309    }
1310
1311    Bool bInterpolateFirst = true; 
1312    Bool bAnyInterpolated  = false; 
1313    for( UInt uiERView = 0; uiERView < m_aiSynthViews.size() && !m_bSetupFromCoded; uiERView++ )
1314    {
1315      Bool bInterpolated = false;
1316      for( UInt uiFrame = m_uiFirstFrameId; uiFrame <= m_uiLastFrameId; uiFrame++ )
1317      {
1318        Bool bInterpolatedCur;
1319        xGetGeometryData( m_aiSynthViews[ uiERView ], uiFrame, dDummy, dDummy, dDummy, bInterpolatedCur );
1320        bInterpolated |= bInterpolatedCur;
1321      }
1322     
1323      if( bInterpolated )
1324      {
1325        bAnyInterpolated = true; 
1326        if ( bInterpolateFirst ) 
1327        {
1328          std::cout << "Interpolating camera parameters      for virtual view(s): " ; 
1329            bInterpolateFirst = false; 
1330        }         
1331        std::cout << (Double)m_aiSynthViews[ uiERView ] / m_dViewNumPrec << " " ; 
1332      }
1333    }
1334    if ( bAnyInterpolated )
1335      std::cout << std::endl;
1336  }
1337
1338  if( bCheckViewRange )
1339  {
1340    Bool bAllExist = true;
1341    for( Int iSynthViewIdx = 0; iSynthViewIdx < m_iNumberOfSynthViews; iSynthViewIdx++ )
1342    {
1343      Bool bIsBaseView;
1344      Int  iDummy;
1345      Bool bExist = getLeftRightBaseView( iSynthViewIdx, iDummy, iDummy, iDummy, bIsBaseView );
1346      bAllExist  &= ( bExist || bIsBaseView );
1347    }
1348    if( !bAllExist )
1349    {
1350      std::cerr << "SynthViewNumbers must be within the range of BaseViewNumbers"  << std::endl;
1351      exit( EXIT_FAILURE );
1352    }
1353  }
1354}
1355
1356
1357Void
1358TAppComCamPara::update( UInt uiFrameId )
1359{
1360
1361  m_iCurrentFrameId = uiFrameId;
1362  m_bCamParsCodedPrecSet = false;
1363
1364  if ( m_bCamParsVaryOverTime )
1365  {
1366    xSetShiftParametersAndLUT( m_uiFirstFrameId + uiFrameId );
1367  }
1368}
1369
1370#if NH_3D_VSO
1371Void
1372TAppComCamPara::setDispCoeff( UInt uiFrameId, Int iViewIdx )
1373{
1374  UInt uiFrame = m_uiFirstFrameId + uiFrameId;
1375  Int  iSourceViewNum = m_aiBaseViews[ iViewIdx ];
1376  Double dBaseLine = 0.0;
1377  Double dFL1 = 1.0, dCS1 = 1.0, dCP1 = 1.0, dZN1 = 1.0, dZF1 = 1.0;
1378  Bool bInterpolated = false;
1379  double dPos[3] = {0.0, 0.0, 0.0};
1380
1381  if( m_iNumberOfBaseViews == 3 )
1382  {
1383    xGetGeometryData( m_aiBaseViews[0], uiFrame, dFL1, dPos[0], dCS1, bInterpolated );
1384    xGetGeometryData( m_aiBaseViews[1], uiFrame, dFL1, dPos[1], dCS1, bInterpolated );
1385    xGetGeometryData( m_aiBaseViews[2], uiFrame, dFL1, dPos[2], dCS1, bInterpolated );
1386
1387    xGetGeometryData( iSourceViewNum, uiFrame, dFL1, dCP1, dCS1, bInterpolated );
1388    xGetZNearZFar   ( iSourceViewNum, uiFrame, dZN1, dZF1 );
1389
1390    dBaseLine = ( std::max( dPos[0], std::max( dPos[1], dPos[2] ) ) - std::min( dPos[0], std::min( dPos[1], dPos[2] ) ) ) / 2.0;
1391  }
1392  else if( m_iNumberOfBaseViews == 2 )
1393  {
1394    xGetGeometryData( m_aiBaseViews[0], uiFrame, dFL1, dPos[0], dCS1, bInterpolated );
1395    xGetGeometryData( m_aiBaseViews[1], uiFrame, dFL1, dPos[1], dCS1, bInterpolated );
1396
1397    xGetGeometryData( iSourceViewNum, uiFrame, dFL1, dCP1, dCS1, bInterpolated );
1398    xGetZNearZFar   ( iSourceViewNum, uiFrame, dZN1, dZF1 );
1399
1400    dBaseLine = dPos[0] - dPos[1];
1401  }
1402
1403  m_dDispCoeff = fabs( dFL1 * ( dBaseLine / 2.0 ) / 255.0 * ( 1.0/dZN1 - 1.0/dZF1 ) );
1404}
1405#endif
1406
1407Bool
1408TAppComCamPara::getLeftRightBaseView( Int iSynthViewIdx, Int &riLeftViewIdx, Int &riRightViewIdx, Int &riRelDistToLeft, Bool& rbIsBaseView )
1409{
1410  Int    iLeftSortedViewIdx, iRightSortedViewIdx, iDummy;
1411  Bool   bExist  = xGetLeftRightView( m_aiSynthViews[ iSynthViewIdx ], m_aiSortedBaseViews, iDummy, iDummy, iLeftSortedViewIdx, iRightSortedViewIdx );
1412  rbIsBaseView   = ( iLeftSortedViewIdx == iRightSortedViewIdx && iLeftSortedViewIdx != -1 );
1413
1414  Int iLeftViewIdx  = ( iLeftSortedViewIdx  != -1 ? m_aiBaseSortedId2Id[ iLeftSortedViewIdx  ] : -1 );
1415  Int iRightViewIdx = ( iRightSortedViewIdx != -1 ? m_aiBaseSortedId2Id[ iRightSortedViewIdx ] : -1 );
1416
1417  if ( iLeftSortedViewIdx != -1 && iRightSortedViewIdx != -1 )
1418  {
1419    riRelDistToLeft = getRelDistLeft(  iSynthViewIdx, iLeftViewIdx, iRightViewIdx);
1420  }
1421  else
1422  {
1423    riRelDistToLeft = -1;
1424  }
1425
1426  riLeftViewIdx  = iLeftViewIdx;
1427  riRightViewIdx = iRightViewIdx;
1428
1429  return bExist;
1430}
1431
1432Bool
1433  TAppComCamPara::xIsIn( std::vector<Int>& rVec, Int iElem) 
1434{
1435  Bool bFound = false; 
1436  for (Int idx = 0; idx < rVec.size() && !bFound; idx++)
1437  {
1438    bFound = bFound || rVec[idx] == iElem; 
1439  }
1440  return bFound;
1441}
1442
1443Int TAppComCamPara::getRelDistLeft( Int iSynthViewIdx, Int iLeftViewIdx, Int iRightViewIdx )
1444{
1445  //GT: Get normalized distance
1446  Int iLeftViewDist  = abs ( m_aiBaseId2SortedId[ iLeftViewIdx  ] * ((Int) m_dViewNumPrec) - m_aiRelSynthViewsNum [ iSynthViewIdx ]);
1447  Int iRightViewDist = abs ( m_aiBaseId2SortedId[ iRightViewIdx ] * ((Int) m_dViewNumPrec) - m_aiRelSynthViewsNum [ iSynthViewIdx ]);
1448  Int64 iDistSum = iLeftViewDist + iRightViewDist;
1449  return (iDistSum == 0) ? (1 << (REN_VDWEIGHT_PREC -1) ) : (Int) (( (((Int64) iLeftViewDist ) << REN_VDWEIGHT_PREC ) + (iDistSum >> 1) )  / iDistSum );
1450}
1451
1452Int
1453TAppComCamPara::synthRelNum2Idx( Int iRelNum )
1454{
1455  return xGetViewId(m_aiRelSynthViewsNum, iRelNum );
1456}
1457#endif
Note: See TracBrowser for help on using the repository browser.