示例#1
0
        public void Invert()
        {
            float	fDet = Determinant();
            if ( (float) System.Math.Abs(fDet) < float.Epsilon )
                throw new Exception( "Matrix is not invertible!" );		// The matrix is not invertible! Singular case!

            float	fIDet = 1.0f / fDet;

            float4x4	Temp = new float4x4();
            Temp[0, 0] = CoFactor( 0, 0 ) * fIDet;
            Temp[1, 0] = CoFactor( 0, 1 ) * fIDet;
            Temp[2, 0] = CoFactor( 0, 2 ) * fIDet;
            Temp[3, 0] = CoFactor( 0, 3 ) * fIDet;
            Temp[0, 1] = CoFactor( 1, 0 ) * fIDet;
            Temp[1, 1] = CoFactor( 1, 1 ) * fIDet;
            Temp[2, 1] = CoFactor( 1, 2 ) * fIDet;
            Temp[3, 1] = CoFactor( 1, 3 ) * fIDet;
            Temp[0, 2] = CoFactor( 2, 0 ) * fIDet;
            Temp[1, 2] = CoFactor( 2, 1 ) * fIDet;
            Temp[2, 2] = CoFactor( 2, 2 ) * fIDet;
            Temp[3, 2] = CoFactor( 2, 3 ) * fIDet;
            Temp[0, 3] = CoFactor( 3, 0 ) * fIDet;
            Temp[1, 3] = CoFactor( 3, 1 ) * fIDet;
            Temp[2, 3] = CoFactor( 3, 2 ) * fIDet;
            Temp[3, 3] = CoFactor( 3, 3 ) * fIDet;

            row0 = Temp.row0;
            row1 = Temp.row1;
            row2 = Temp.row2;
            row3 = Temp.row3;
        }
示例#2
0
        /// <summary>
        /// Builds the RGB<->XYZ transforms from chromaticities
        /// (refer to http://wiki.nuaj.net/index.php/Color_Transforms#XYZ_Matrices for explanations)
        /// </summary>
        protected void BuildTransformFromChroma( bool _bCheckGammaCurveOverride )
        {
            float3	xyz_R = new float3( m_Chromaticities.R.x, m_Chromaticities.R.y, 1.0f - m_Chromaticities.R.x - m_Chromaticities.R.y );
            float3	xyz_G = new float3( m_Chromaticities.G.x, m_Chromaticities.G.y, 1.0f - m_Chromaticities.G.x - m_Chromaticities.G.y );
            float3	xyz_B = new float3( m_Chromaticities.B.x, m_Chromaticities.B.y, 1.0f - m_Chromaticities.B.x - m_Chromaticities.B.y );
            float3	XYZ_W = xyY2XYZ( new float3( m_Chromaticities.W.x, m_Chromaticities.W.y, 1.0f ) );

            float4x4	M_xyz = new float4x4() {
                row0 = new float4( xyz_R, 0.0f ),
                row1 = new float4( xyz_G, 0.0f ),
                row2 = new float4( xyz_B, 0.0f ),
                row3 = new float4( 0.0f, 0.0f, 0.0f, 1.0f )
            };

            M_xyz.Invert();

            float4	Sum_RGB = new float4( XYZ_W, 1.0f ) * M_xyz;

            // Finally, we can retrieve the RGB->XYZ transform
            m_RGB2XYZ.row0 = new float4( Sum_RGB.x * xyz_R, 0.0f );
            m_RGB2XYZ.row1 = new float4( Sum_RGB.y * xyz_G, 0.0f );
            m_RGB2XYZ.row2 = new float4( Sum_RGB.z * xyz_B, 0.0f );

            // And the XYZ->RGB transform
            m_XYZ2RGB = m_RGB2XYZ;
            m_XYZ2RGB.Invert();

            // ============= Attempt to recognize a standard profile =============
            STANDARD_PROFILE	RecognizedChromaticity = m_Chromaticities.RecognizedChromaticity;

            if ( _bCheckGammaCurveOverride )
            {	// Also ensure the gamma ramp is correct before assigning a standard profile
                bool	bIsGammaCorrect = true;
                switch ( RecognizedChromaticity )
                {
                    case STANDARD_PROFILE.sRGB:				bIsGammaCorrect = EnsureGamma( GAMMA_CURVE.sRGB, GAMMA_EXPONENT_sRGB ); break;
                    case STANDARD_PROFILE.ADOBE_RGB_D50:	bIsGammaCorrect = EnsureGamma( GAMMA_CURVE.STANDARD, GAMMA_EXPONENT_ADOBE ); break;
                    case STANDARD_PROFILE.ADOBE_RGB_D65:	bIsGammaCorrect = EnsureGamma( GAMMA_CURVE.STANDARD, GAMMA_EXPONENT_ADOBE ); break;
                    case STANDARD_PROFILE.PRO_PHOTO:		bIsGammaCorrect = EnsureGamma( GAMMA_CURVE.PRO_PHOTO, GAMMA_EXPONENT_PRO_PHOTO ); break;
                    case STANDARD_PROFILE.RADIANCE:			bIsGammaCorrect = EnsureGamma( GAMMA_CURVE.STANDARD, 1.0f ); break;
                }

                if ( !bIsGammaCorrect )
                    RecognizedChromaticity = STANDARD_PROFILE.CUSTOM;	// A non-standard gamma curves fails our pre-defined design...
            }

            // ============= Assign the internal converter depending on the profile =============
            switch ( RecognizedChromaticity )
            {
                case STANDARD_PROFILE.sRGB:
                    m_GammaCurve = GAMMA_CURVE.sRGB;
                    m_Gamma = GAMMA_EXPONENT_sRGB;
                    m_InternalConverter = new InternalColorConverter_sRGB();
                    break;

                case STANDARD_PROFILE.ADOBE_RGB_D50:
                    m_GammaCurve = GAMMA_CURVE.STANDARD;
                    m_Gamma = GAMMA_EXPONENT_ADOBE;
                    m_InternalConverter = new InternalColorConverter_AdobeRGB_D50();
                    break;

                case STANDARD_PROFILE.ADOBE_RGB_D65:
                    m_GammaCurve = GAMMA_CURVE.STANDARD;
                    m_Gamma = GAMMA_EXPONENT_ADOBE;
                    m_InternalConverter = new InternalColorConverter_AdobeRGB_D65();
                    break;

                case STANDARD_PROFILE.PRO_PHOTO:
                    m_GammaCurve = GAMMA_CURVE.PRO_PHOTO;
                    m_Gamma = GAMMA_EXPONENT_PRO_PHOTO;
                    m_InternalConverter = new InternalColorConverter_ProPhoto();
                    break;

                case STANDARD_PROFILE.RADIANCE:
                    m_GammaCurve = GAMMA_CURVE.STANDARD;
                    m_Gamma = 1.0f;
                    m_InternalConverter = new InternalColorConverter_Radiance();
                    break;

                default:	// Switch to one of our generic converters
                    switch ( m_GammaCurve )
                    {
                        case GAMMA_CURVE.sRGB:
                            m_InternalConverter = new InternalColorConverter_Generic_sRGBGamma( m_RGB2XYZ, m_XYZ2RGB );
                            break;
                        case GAMMA_CURVE.PRO_PHOTO:
                            m_InternalConverter = new InternalColorConverter_Generic_ProPhoto( m_RGB2XYZ, m_XYZ2RGB );
                            break;
                        case GAMMA_CURVE.STANDARD:
                            if ( Math.Abs( m_Gamma - 1.0f ) < 1e-3f )
                                m_InternalConverter = new InternalColorConverter_Generic_NoGamma( m_RGB2XYZ, m_XYZ2RGB );
                            else
                                m_InternalConverter = new InternalColorConverter_Generic_StandardGamma( m_RGB2XYZ, m_XYZ2RGB, m_Gamma );
                            break;
                    }
                    break;
            }
        }
示例#3
0
 public InternalColorConverter_Generic_sRGBGamma( float4x4 _RGB2XYZ, float4x4 _XYZ2RGB )
 {
     m_RGB2XYZ = _RGB2XYZ;
     m_XYZ2RGB = _XYZ2RGB;
 }
示例#4
0
 public InternalColorConverter_Generic_StandardGamma( float4x4 _RGB2XYZ, float4x4 _XYZ2RGB, float _Gamma )
 {
     m_RGB2XYZ = _RGB2XYZ;
     m_XYZ2RGB = _XYZ2RGB;
     m_Gamma = _Gamma;
     m_InvGamma = 1.0f / _Gamma;
 }
示例#5
0
 public InternalColorConverter_Generic_ProPhoto( float4x4 _RGB2XYZ, float4x4 _XYZ2RGB )
 {
     m_RGB2XYZ = _RGB2XYZ;
     m_XYZ2RGB = _XYZ2RGB;
 }