| 96 | } |
| 97 | |
| 98 | Vector3d TriColorFromKelvin( float temperature, float tint, Tr2StandardIlluminant whitePoint ) |
| 99 | { |
| 100 | double xc, yc; |
| 101 | const double T = temperature; |
| 102 | const double Y = 1.0; |
| 103 | |
| 104 | if( T < 1000.0f || T > 25000.0f ) |
| 105 | { |
| 106 | return Vector3d( 0.0, 0.0, 0.0 ); |
| 107 | } |
| 108 | |
| 109 | |
| 110 | if( T >= 1000.0f && T <= 4000.0f ) |
| 111 | { |
| 112 | xc = -0.2661239 * ( 1000000000.0 / ( T * T * T ) ) - |
| 113 | 0.2343580 * ( 1000000.0 / ( T * T ) ) + |
| 114 | 0.8776956 * ( 1000.0 / T ) + |
| 115 | 0.179910; |
| 116 | } |
| 117 | else |
| 118 | { |
| 119 | xc = -3.0258469 * ( 1000000000.0 / ( T * T * T ) ) + |
| 120 | 2.1070379 * ( 1000000.0 / ( T * T ) ) + |
| 121 | 0.2226347 * ( 1000.0 / T ) + |
| 122 | 0.24039; |
| 123 | } |
| 124 | |
| 125 | if( T >= 1000.0f && T <= 2222.0f ) |
| 126 | { |
| 127 | yc = -1.1063814 * ( xc * xc * xc ) - |
| 128 | 1.3481102 * ( xc * xc ) + |
| 129 | 2.1855583 * xc - |
| 130 | 0.20219683; |
| 131 | } |
| 132 | else if( T > 2222.0f && T <= 4000.0 ) |
| 133 | { |
| 134 | yc = -0.9549476 * ( xc * xc * xc ) - |
| 135 | 1.3741859 * ( xc * xc ) + |
| 136 | 2.09137015 * xc - |
| 137 | 0.16748867; |
| 138 | } |
| 139 | else |
| 140 | { |
| 141 | yc = 3.081758 * ( xc * xc * xc ) - |
| 142 | 5.8733867 * ( xc * xc ) + |
| 143 | 3.75112997 * xc - |
| 144 | 0.37001483; |
| 145 | } |
| 146 | |
| 147 | // Compute base correlated color temperature |
| 148 | const double X = ( Y / yc ) * xc; |
| 149 | const double Z = ( Y / yc ) * ( 1.0 - xc - yc ); |
| 150 | const Vector3d cctXYZ( X, Y, Z ); |
| 151 | |
| 152 | // Compute white balance |
| 153 | const double wbY = 0.54; |
| 154 | Vector2 wbCoeff = Tr2StandardIlluminantToCCT( whitePoint ); |
| 155 | const double wbX = ( wbY / (double)wbCoeff.y ) * (double)wbCoeff.x; |
no test coverage detected