00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #include "camtypes.h"
00106
00107
00108 #include "clamp.h"
00109
00110
00111
00112
00113
00114
00115
00116
00118
00119 const AFp CProfileBiasGain::kSmallAmount_s( 0.00001 );
00120
00121
00122
00123
00124
00125
00126
00127
00129
00135
00136 CProfileBiasGain::CProfileBiasGain ()
00137 : IProfile()
00138
00139
00140
00141
00142
00143
00144
00145
00146 {
00147
00148 CProfileBiasGain::SetBiasGain( AFp(0.0), AFp(0.0) );
00149 CProfileBiasGain::SetDefaultIntervals();
00150 generatesInfiniteUndo = FALSE;
00151 }
00152
00153
00160
00161 CProfileBiasGain::CProfileBiasGain ( AFp BiasMinus1ToPlus1, AFp GainMinus1ToPlus1 )
00162 : IProfile()
00163
00164
00165
00166
00167
00168
00169
00170
00171 {
00172
00173 CProfileBiasGain::SetBiasGain( BiasMinus1ToPlus1, GainMinus1ToPlus1 );
00174 CProfileBiasGain::SetDefaultIntervals();
00175 generatesInfiniteUndo = FALSE;
00176 }
00177
00178
00179
00180
00181 CProfileBiasGain::~CProfileBiasGain ()
00182 {
00183 }
00184
00185
00186
00187
00188 CProfileBiasGain::CProfileBiasGain ( const CProfileBiasGain& Other )
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 {
00199
00200 CProfileBiasGain::operator=( Other );
00201
00202 }
00203
00204
00205
00206
00207 CProfileBiasGain& CProfileBiasGain::operator= ( const CProfileBiasGain& Other )
00208 {
00209
00210 IProfile::operator=( Other );
00211
00212 BiasMinus1ToPlus1_m = Other.BiasMinus1ToPlus1_m;
00213 GainMinus1ToPlus1_m = Other.GainMinus1ToPlus1_m;
00214 Bias_m = Other.Bias_m;
00215 Gain_m = Other.Gain_m;
00216
00217 DomainLow_m = Other.DomainLow_m;
00218 DomainLength_m = Other.DomainLength_m;
00219 RangeLow_m = Other.RangeLow_m;
00220 RangeLength_m = Other.RangeLength_m;
00221
00222 return *this;
00223
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00234
00236
00243
00244 void CProfileBiasGain::SetBiasGain ( AFp BiasMinus1ToPlus1, AFp GainMinus1ToPlus1 )
00245 {
00246
00247 SetBias( BiasMinus1ToPlus1 );
00248 SetGain( GainMinus1ToPlus1 );
00249
00250 }
00251
00252
00259
00260 void CProfileBiasGain::SetBias ( AFp BiasMinus1ToPlus1 )
00261 {
00262
00264 BiasMinus1ToPlus1 = ClampBetween( BiasMinus1ToPlus1, AFp(-1.0), AFp(+1.0) );
00265
00266
00268 const AFp BiasZeroToOne( ConvertIntervalMinus1Plus1ToZeroOne( BiasMinus1ToPlus1 ) );
00269
00270
00272 BiasMinus1ToPlus1_m = BiasMinus1ToPlus1;
00273 Bias_m = BiasZeroToOne;
00274
00275 }
00276
00277
00284
00285 void CProfileBiasGain::SetGain ( AFp GainMinus1ToPlus1 )
00286 {
00287
00289 GainMinus1ToPlus1 = ClampBetween( GainMinus1ToPlus1, AFp(-1.0), AFp(+1.0) );
00290
00291
00293 const AFp GainZeroToOne( ConvertIntervalMinus1Plus1ToZeroOne( GainMinus1ToPlus1 ) );
00294
00295
00297 GainMinus1ToPlus1_m = GainMinus1ToPlus1;
00298 Gain_m = GainZeroToOne;
00299
00300 }
00301
00302
00303 AFp CProfileBiasGain::GetBias () const
00304 {
00305
00306 return BiasMinus1ToPlus1_m;
00307
00308 }
00309
00310
00311 AFp CProfileBiasGain::GetGain () const
00312 {
00313
00314 return GainMinus1ToPlus1_m;
00315
00316 }
00317
00318
00319
00320
00322
00330
00331 AFp CProfileBiasGain::MapZeroToOne ( AFp InputZeroToOne ) const
00332 {
00333
00335 InputZeroToOne = ClampBetween( InputZeroToOne, AFp(0.0), AFp(1.0) );
00336
00337
00339 AFp BiasedGained( 0.0 );
00340 {
00343 if( ( BiasMinus1ToPlus1_m != AFp(0.0) )
00344 || ( GainMinus1ToPlus1_m != AFp(0.0) ) )
00345 {
00347 BiasedGained = BiasGain( Bias_m, Gain_m, InputZeroToOne );
00348 }
00349 else
00350 {
00351 BiasedGained = InputZeroToOne;
00352 }
00353 }
00354
00355
00356 return BiasedGained;
00357
00358 }
00359
00360
00361
00362
00364
00371
00372 void CProfileBiasGain::SetIntervals ( AFp Low, AFp High )
00373 {
00374
00375 SetIntervals( Low, High, Low, High );
00376
00377 }
00378
00379
00386
00387 void CProfileBiasGain::SetIntervals ( AFp DomainLow, AFp DomainHigh, AFp RangeLow, AFp RangeHigh )
00388 {
00389
00390 AFp DomainLength( DomainHigh - DomainLow );
00391 AFp RangeLength( RangeHigh - RangeLow );
00392
00393
00395 if( DomainLength == AFp(0.0) )
00396 {
00397 DomainLength = kSmallAmount_s;
00398 }
00399 if( RangeLength == AFp(0.0) )
00400 {
00401 RangeLength = kSmallAmount_s;
00402 }
00403
00404
00406 DomainLow_m = DomainLow;
00407 DomainLength_m = DomainLength;
00408
00409 RangeLow_m = RangeLow;
00410 RangeLength_m = RangeLength;
00411
00412 }
00413
00414
00422
00423 AFp CProfileBiasGain::MapInterval ( AFp InputDomain ) const
00424 {
00425
00427 InputDomain = ClampBetween( InputDomain, DomainLow_m, DomainLow_m + DomainLength_m );
00428
00429
00431 const AFp InputZeroToOne( ScaleDomainToZeroOne( InputDomain ) );
00432
00434 const AFp BiasedGained( MapZeroToOne( InputZeroToOne ) );
00435
00437 const AFp OutputRange( ScaleZeroOneToRange( BiasedGained ) );
00438
00439
00440 return OutputRange;
00441
00442 }
00443
00444
00452
00453 void CProfileBiasGain::MapInterval ( AFp Table[], INT32 TableLength ) const
00454 {
00455
00457 if( Table != 0 )
00458 {
00459
00461 const AFp Increment( AFp(1.0) / AFp(TableLength) );
00462 AFp InputZeroOne( 0.0 );
00463
00464
00466 for( INT32 Index = 0 ; Index < TableLength ; ++Index )
00467 {
00468 const AFp BiasedGained( MapZeroToOne( InputZeroOne ) );
00469 const AFp OutputRange( ScaleZeroOneToRange( BiasedGained ) );
00470
00471 Table[ Index ] = OutputRange;
00472
00473 InputZeroOne += Increment;
00474 }
00475
00476 }
00477
00478 }
00479
00480
00481
00482
00484
00485 bool CProfileBiasGain::operator== ( const CProfileBiasGain& Other ) const
00486 {
00487
00489 const bool IsSame = ( Bias_m == Other.Bias_m )
00490 && ( Gain_m == Other.Gain_m );
00491
00492 return IsSame;
00493
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00504
00506
00515
00516 AFp CProfileBiasGain::ConvertIntervalMinus1Plus1ToZeroOne ( AFp Minus1ToPlus1 )
00517 {
00518
00519
00520 static const AFp kShrink( ( AFp(1.0) / AFp(2.0) ) - kSmallAmount_s );
00521
00522 const AFp ZeroToOne( ( Minus1ToPlus1 + AFp(1.0) ) * kShrink + kSmallAmount_s );
00523
00524
00525 return ZeroToOne;
00526
00527 }
00528
00529
00530 AFp CProfileBiasGain::ScaleDomainToZeroOne ( AFp InDomain ) const
00531 {
00532
00534 if( DomainLength_m != AFp(0.0) )
00535 {
00536 return ( InDomain - DomainLow_m ) / DomainLength_m;
00537 }
00538 else
00539 {
00540 return AFp( 0.0 );
00541 }
00542
00543 }
00544
00545
00546 AFp CProfileBiasGain::ScaleZeroOneToRange ( AFp InZeroOne ) const
00547 {
00548
00549 return ( InZeroOne * RangeLength_m ) + RangeLow_m;
00550
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00561
00571
00572 AFp CProfileBiasGain::BiasGain ( AFp bias, AFp gain, AFp Input )
00573 {
00574
00575 const AFp Biased( Bias( bias, Input ) );
00576 const AFp Output( Gain( gain, Biased ) );
00577
00578 return Output;
00579
00580 }
00581
00582
00591
00592 AFp CProfileBiasGain::Bias ( AFp Bias, AFp Input )
00593 {
00594
00595 static const AFp kOne( 1.0 );
00596 static const AFp kTwo( 2.0 );
00597
00598
00599 const AFp Output( Input*Bias / ( ( kOne - kTwo*Bias ) * ( kOne - Input ) + Bias ) );
00600
00601
00602 return Output;
00603
00604 }
00605
00606
00615
00616 AFp CProfileBiasGain::Gain ( AFp Gain, AFp Input )
00617 {
00618
00619 static const AFp kOne( 1.0 );
00620 static const AFp kTwo( 2.0 );
00621 static const AFp kHalf( 0.5 );
00622
00623
00624 const AFp CommonPart( ( kOne - kTwo*Gain ) * ( kOne - kTwo * Input ) );
00625
00626 if( Input < kHalf )
00627 {
00628
00629 return Input*Gain / ( CommonPart + Gain );
00630 }
00631 else
00632 {
00633
00634 return ( CommonPart - Input*Gain ) / ( CommonPart - Gain );
00635 }
00636
00637 }
00638
00639
00640
00641
00643
00644 void CProfileBiasGain::SetDefaultIntervals ()
00645 {
00646
00647 DomainLow_m = AFp( 0.0 );
00648 DomainLength_m = AFp( 1.0 );
00649 RangeLow_m = AFp( 0.0 );
00650 RangeLength_m = AFp( 1.0 );
00651
00652 }