text: /*****************************************************************************/
  // Copyright 2006-2008 Adobe Systems Incorporated
  // All Rights Reserved.
  //
  // NOTICE:  Adobe permits you to use, modify, and distribute this file in
  // accordance with the terms of the Adobe license agreement accompanying it.
  /*****************************************************************************/
  
  /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_matrix.h#2 $ */ 
  /* $DateTime: 2012/07/31 22:04:34 $ */
  /* $Change: 840853 $ */
  /* $Author: tknoll $ */
  
  /** \file
   * Matrix and vector classes, including specialized 3x3 and 4x3 versions as
   * well as length 3 vectors.
   */
  
  /*****************************************************************************/
  
  #ifndef __dng_matrix__
  #define __dng_matrix__
  
  /*****************************************************************************/
  
  #include "dng_sdk_limits.h"
  #include "dng_types.h"
  
  /*****************************************************************************/
  
  /// \brief Class to represent 2D matrix up to kMaxColorPlanes x kMaxColorPlanes
  /// in size.
  
  class dng_matrix
  	{
  	
  	protected:
  	
  		uint32 fRows;
  		uint32 fCols;
  	
  		real64 fData [kMaxColorPlanes] [kMaxColorPlanes];
  		
  	public:
  	
  		dng_matrix ();
  					
  		dng_matrix (uint32 rows,
  					uint32 cols);
  					
  		dng_matrix (const dng_matrix &m);
  		
  		virtual ~dng_matrix ()
  			{
  			}
  		
  		void Clear ();
  		
  		void SetIdentity (uint32 count);
  		
  		uint32 Rows () const
  			{
  			return fRows;
  			}
  			
  		uint32 Cols () const
  			{
  			return fCols;
  			}
  			
  		real64 * operator [] (uint32 row)
  			{
  			return fData [row];
  			}
  			
  		const real64 * operator [] (uint32 row) const
  			{
  			return fData [row];
  			}
  			
  		bool operator== (const dng_matrix &m) const;
  		
  		bool operator!= (const dng_matrix &m) const
  			{
  			return !(*this == m);
  			}
  			
  		bool IsEmpty () const
  			{
  			return fRows == 0 || fCols == 0;
  			}
  			
  		bool NotEmpty () const
  			{
  			return !IsEmpty ();
  			}
  			
  		bool IsDiagonal () const;
  			
  		real64 MaxEntry () const;
  		
  		real64 MinEntry () const;
  
  		void Scale (real64 factor);
  			
  		void Round (real64 factor);
  		
  		void SafeRound (real64 factor);
  
  	};
  	
  /*****************************************************************************/
  
  /// \brief A 3x3 matrix.
  
  class dng_matrix_3by3: public dng_matrix
  	{
  	
  	public:
  	
  		dng_matrix_3by3 ();
  		
  		dng_matrix_3by3 (const dng_matrix &m);
  		
  		dng_matrix_3by3 (real64 a00, real64 a01, real64 a02,
  				         real64 a10, real64 a11, real64 a12,
  				         real64 a20, real64 a21, real64 a22);
  				    
  		dng_matrix_3by3 (real64 a00, real64 a11, real64 a22);
  	
  	};
  
  /*****************************************************************************/
  
  /// \brief A 4x3 matrix. Handy for working with 4-color cameras.
  
  class dng_matrix_4by3: public dng_matrix
  	{
  	
  	public:
  	
  		dng_matrix_4by3 ();
  		
  		dng_matrix_4by3 (const dng_matrix &m);
  		
  		dng_matrix_4by3 (real64 a00, real64 a01, real64 a02,
  				         real64 a10, real64 a11, real64 a12,
  				         real64 a20, real64 a21, real64 a22,
  				         real64 a30, real64 a31, real64 a32);
  	
  	};
  
  /*****************************************************************************/
  
  /// \brief Class to represent 1-dimensional vector with up to kMaxColorPlanes
  /// components.
  
  class dng_vector
  	{
  	
  	protected:
  	
  		uint32 fCount;
  		
  		real64 fData [kMaxColorPlanes];
  		
  	public:
  	
  		dng_vector ();
  		
  		dng_vector (uint32 count);
  		
  		dng_vector (const dng_vector &v);
  		
  		virtual ~dng_vector ()
  			{
  			}
  		
  		void Clear ();
  		
  		void SetIdentity (uint32 count);
  		
  		uint32 Count () const
  			{
  			return fCount;
  			}
  			
  		real64 & operator [] (uint32 index)
  			{
  			return fData [index];
  			}
  			
  		const real64 & operator [] (uint32 index) const
  			{
  			return fData [index];
  			}
  			
  		bool operator== (const dng_vector &v) const;
  		
  		bool operator!= (const dng_vector &v) const
  			{
  			return !(*this == v);
  			}
  			
  		bool IsEmpty () const
  			{
  			return fCount == 0;
  			}
  			
  		bool NotEmpty () const
  			{
  			return !IsEmpty ();
  			}
  
  		real64 MaxEntry () const;
  		
  		real64 MinEntry () const;
  
  		void Scale (real64 factor);
  			
  		void Round (real64 factor);
  
  		dng_matrix AsDiagonal () const;
  		
  		dng_matrix AsColumn () const;
  		
  	};
  
  /*****************************************************************************/
  
  /// \brief A 3-element vector.
  
  class dng_vector_3: public dng_vector
  	{
  	
  	public:
  	
  		dng_vector_3 ();
  		
  		dng_vector_3 (const dng_vector &v);
  		
  		dng_vector_3 (real64 a0,
  					  real64 a1,
  					  real64 a2);
  	
  	};
  
  /*****************************************************************************/
  
  /// \brief A 4-element vector.
  
  class dng_vector_4: public dng_vector
  	{
  	
  	public:
  	
  		dng_vector_4 ();
  		
  		dng_vector_4 (const dng_vector &v);
  		
  		dng_vector_4 (real64 a0,
  					  real64 a1,
  					  real64 a2,
  					  real64 a3);
  	
  	};
  
  /*****************************************************************************/
  
  dng_matrix operator* (const dng_matrix &A,
  					  const dng_matrix &B);
  
  dng_vector operator* (const dng_matrix &A,
  					  const dng_vector &B);
  
  dng_matrix operator* (real64 scale,
  					  const dng_matrix &A);
  
  dng_vector operator* (real64 scale,
  					  const dng_vector &A);
  
  /*****************************************************************************/
  
  dng_matrix operator+ (const dng_matrix &A,
  					  const dng_matrix &B);
  
  /*****************************************************************************/
  
  dng_matrix Transpose (const dng_matrix &A);
  
  /*****************************************************************************/
  
  dng_matrix Invert (const dng_matrix &A);
  
  dng_matrix Invert (const dng_matrix &A,
  				   const dng_matrix &hint);
  
  /*****************************************************************************/
  
  inline real64 MaxEntry (const dng_matrix &A)
  	{
  	return A.MaxEntry ();
  	}
  		
  inline real64 MaxEntry (const dng_vector &A)
  	{
  	return A.MaxEntry ();
  	}
  					  
  /*****************************************************************************/
  
  inline real64 MinEntry (const dng_matrix &A)
  	{
  	return A.MinEntry ();
  	}
  		
  inline real64 MinEntry (const dng_vector &A)
  	{
  	return A.MinEntry ();
  	}
  					  
  /*****************************************************************************/
  
  #endif
  	
  /*****************************************************************************/
  