source: 3DVCSoftware/branches/HTM-4.0.1-VSP-dev0/source/Lib/TAppCommon/TAppComCamPara.cpp

Last change on this file was 166, checked in by mitsubishi-htm, 12 years ago

Initial integration of VSP into HTM 4.0.1. The version used for JCT3V-B0102 at Shanghai meeting.

  • VC9 project/solution files updated. Other Visual C++ project/solution files are not updated.
  • Linux make file updated.

TODO

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