channel_converter.cpp 1.89 KB
Newer Older
Emanuele Tamponi's avatar
Emanuele Tamponi committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 *  Copyright (c) 2007 Emanuele Tamponi <emanuele@valinor.it>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Emanuele Tamponi's avatar
Emanuele Tamponi committed
18
 */
Emanuele Tamponi's avatar
Emanuele Tamponi committed
19 20 21

#include <cmath>

Emanuele Tamponi's avatar
Emanuele Tamponi committed
22
#include "channel_converter.h"
Emanuele Tamponi's avatar
Emanuele Tamponi committed
23

Emanuele Tamponi's avatar
Emanuele Tamponi committed
24
ChannelConverter::ChannelConverter(float whiteS, float blackK)
Emanuele Tamponi's avatar
Emanuele Tamponi committed
25 26 27 28
: S_w(whiteS), K_b(blackK)
{
}

Emanuele Tamponi's avatar
Emanuele Tamponi committed
29
ChannelConverter::~ChannelConverter()
Emanuele Tamponi's avatar
Emanuele Tamponi committed
30 31 32
{
}

Emanuele Tamponi's avatar
Emanuele Tamponi committed
33
void ChannelConverter::KSToReflectance(float K, float S, float &R) const
Emanuele Tamponi's avatar
Emanuele Tamponi committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
{
    if (S == 0.0) {
        R = 0.0;
        return;
    }

    if (K == 0.0) {
        R = 1.0;
        return;
    }

    float Q = K/S;
    R = 1.0 + Q - sqrt( Q*Q + 2.0*Q );
}

Emanuele Tamponi's avatar
Emanuele Tamponi committed
49
void ChannelConverter::reflectanceToKS(float R, float &K, float &S) const
Emanuele Tamponi's avatar
Emanuele Tamponi committed
50
{
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    if ( R == 0.0 ) {
        K = 0.8 * K_b;
        S = 0.0;
        return;
    }
    if ( R == 1.0 ) {
        K = 0.0;
        S = 0.8 * S_w;
        return;
    }
    if ( R <= 0.5 ) {
        float Rw = ( 1.0 + R ) / 2.0;
        float F  = ( 2.0 * R  ) / pow ( 1.0 - R , 2 );
        float Fw = ( 2.0 * Rw ) / pow ( 1.0 - Rw, 2 );
        K = S_w / ( Fw - F );
        S = K * F;
    }
    if ( R > 0.5 ) {
        float Rb = R / 2.0;
        float P  = pow ( 1.0 - R , 2 ) / ( 2.0 * R  );
        float Pb = pow ( 1.0 - Rb, 2 ) / ( 2.0 * Rb );
        S = K_b / ( Pb - P );
        K = S * P;
    }
Emanuele Tamponi's avatar
Emanuele Tamponi committed
75
}