PixelsTypes.H

Go to the documentation of this file.
00001 /*!@file Image/PixelsTypes.H Basic pixel types version 2.0 */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/PixelsTypes.H $
00035 // $Id: PixelsTypes.H 12962 2010-03-06 02:13:53Z irock $
00036 //
00037 
00038 #ifndef PIXELSTYPES_H_DEFINED
00039 #define PIXELSTYPES_H_DEFINED
00040 
00041 #include "Util/MathFunctions.H"  // for clampValue()
00042 #include "Image/PixelsBase.H"
00043 #include "Image/PixelsCommonDef.H"
00044 #include "Util/Promotions.H"
00045 #include "Util/TypeTraits.H"
00046 #include "Util/Assert.H"
00047 #include "Util/Types.H"
00048 #include "Util/log.H"
00049 #include "Image/colorDefs.H"
00050 
00051 #include <cmath>
00052 
00053 // ######################################################################
00054 // ######################################################################
00055 // Derived pixel classes that hold type conversion information
00056 // ######################################################################
00057 // ######################################################################
00058 
00059 template <class T>             class PixRGB;
00060 template <class T>             class PixHSV;
00061 template <class T>             class PixJpegYUV;
00062 template <class T>             class PixVideoYUV;
00063 template <class T>             class PixYIQ;
00064 template <class T>             class PixHSL;
00065 template <class T>             class PixLab;
00066 template <class T>             class PixXYZ;
00067 template <class T>             class PixH2SV1;
00068 template <class T>             class PixH2SV2;
00069 template <class T>             class PixH2SV3;
00070 template <class T, size_t dim> class PixHyper;
00071 template <class T>             class PixDKL;
00072 
00073 //! Specialize TypeTraits to indicate that PixRGB is a "trivial" type.
00074 /*! That is, it is a type that can be safely initialized with memset(), and
00075     safely copied with memcpy(). In practical terms, this means we're
00076     relying on PixRGB not to do anything significant in its copy
00077     constructor or destructor. */
00078 
00079 template <class T> struct TypeTraits<PixRGB<T> >
00080 {
00081   enum { isTrivial = TypeTraits<T>::isTrivial };
00082 };
00083 //! Specialize TypeTraits to indicate that PixHSV is a "trivial" type.
00084 template <class T> struct TypeTraits<PixHSV<T> >
00085 {
00086   enum { isTrivial = TypeTraits<T>::isTrivial };
00087 };
00088 //! Specialize TypeTraits to indicate that PixJpegYUV is a "trivial" type.
00089 template <class T> struct TypeTraits<PixJpegYUV<T> >
00090 {
00091   enum { isTrivial = TypeTraits<T>::isTrivial };
00092 };
00093 //! Specialize TypeTraits to indicate that PixVideoYUV is a "trivial" type.
00094 template <class T> struct TypeTraits<PixVideoYUV<T> >
00095 {
00096   enum { isTrivial = TypeTraits<T>::isTrivial };
00097 };
00098 //! Specialize TypeTraits to indicate that PixYIQ is a "trivial" type.
00099 template <class T> struct TypeTraits<PixYIQ<T> >
00100 {
00101   enum { isTrivial = TypeTraits<T>::isTrivial };
00102 };
00103 //! Specialize TypeTraits to indicate that PixHSL is a "trivial" type.
00104 template <class T> struct TypeTraits<PixHSL<T> >
00105 {
00106   enum { isTrivial = TypeTraits<T>::isTrivial };
00107 };
00108 //! Specialize TypeTraits to indicate that PixLab is a "trivial" type.
00109 template <class T> struct TypeTraits<PixLab<T> >
00110 {
00111   enum { isTrivial = TypeTraits<T>::isTrivial };
00112 };
00113 //! Specialize TypeTraits to indicate that PixXYZ is a "trivial" type.
00114 template <class T> struct TypeTraits<PixXYZ<T> >
00115 {
00116   enum { isTrivial = TypeTraits<T>::isTrivial };
00117 };
00118 //! Specialize TypeTraits to indicate that PixH2SV1 is a "trivial" type.
00119 template <class T> struct TypeTraits<PixH2SV1<T> >
00120 {
00121   enum { isTrivial = TypeTraits<T>::isTrivial };
00122 };
00123 //! Specialize TypeTraits to indicate that PixH2SV2 is a "trivial" type.
00124 template <class T> struct TypeTraits<PixH2SV2<T> >
00125 {
00126   enum { isTrivial = TypeTraits<T>::isTrivial };
00127 };
00128 //! Specialize TypeTraits to indicate that PixH2SV3 is a "trivial" type.
00129 template <class T> struct TypeTraits<PixH2SV3<T> >
00130 {
00131   enum { isTrivial = TypeTraits<T>::isTrivial };
00132 };
00133 //! Specialize TypeTraits to indicate that PixHyper is a "trivial" type.
00134 template <class T, size_t dim> struct TypeTraits<PixHyper<T,dim> >
00135 {
00136   enum { isTrivial = TypeTraits<T>::isTrivial };
00137 };
00138 //! Specialize TypeTraits to indicate that PixDKL is a "trivial" type.
00139 template <class T> struct TypeTraits<PixDKL<T> >
00140 {
00141   enum { isTrivial = TypeTraits<T>::isTrivial };
00142 };
00143 
00144 
00145 namespace ops
00146 {
00147   struct plus
00148   {
00149     template <class T, class U>
00150     typename promote_trait<T,U>::TP
00151     operator()(const T& t, const U& u) { return t+u; }
00152   };
00153 
00154   struct minus
00155   {
00156     template <class T, class U>
00157     typename promote_trait<T,U>::TP
00158     operator()(const T& t, const U& u) { return t-u; }
00159   };
00160 
00161   struct multiplies
00162   {
00163     template <class T, class U>
00164     typename promote_trait<T,U>::TP
00165     operator()(const T& t, const U& u) { return t*u; }
00166   };
00167 
00168   struct divides
00169   {
00170     template <class T, class U>
00171     typename promote_trait<T,U>::TP
00172     operator()(const T& t, const U& u) { return t/u; }
00173   };
00174 
00175   struct modulo
00176   {
00177     template <class T, class U>
00178     typename promote_trait<T,U>::TP
00179     operator()(const T& t, const U& u) { return t%u; }
00180   };
00181 
00182   struct bitwise_and
00183   {
00184     template <class T, class U>
00185     typename promote_trait<T,U>::TP
00186     operator()(const T& t, const U& u) { return t&u; }
00187   };
00188 
00189   struct bitwise_or
00190   {
00191     template <class T, class U>
00192     typename promote_trait<T,U>::TP
00193     operator()(const T& t, const U& u) { return t|u; }
00194   };
00195 
00196   struct bitwise_xor
00197   {
00198     template <class T, class U>
00199     typename promote_trait<T,U>::TP
00200     operator()(const T& t, const U& u) { return t^u; }
00201   };
00202 
00203 }
00204 
00205 
00206 //! Helper struct to provide a generic way to "rebind" template parameters.
00207 /*! That is, this gives us a way to get Foo<T2> if we are given
00208     Foo<T>, or to get Bar<T2, U> if we are given Bar<T, U>. In
00209     particular, this lets us write generic functions that can deal
00210     with pixel types that have either a single template parameter
00211     (e.g. PixRGB<T>, PixHSV<T>), or more than one template parameter
00212     (e.g. PixHyper<T, dim>). */
00213 template <class C, class T>
00214 struct rebind
00215 {};
00216 
00217 template <template <class> class C,
00218           class T, class U>
00219 struct rebind<C<T>, U>
00220 {
00221   typedef C<U> type;
00222 };
00223 
00224 template <template <class, size_t> class C,
00225           class T1, size_t T2, class U1>
00226 struct rebind<C<T1, T2>, U1>
00227 {
00228   typedef C<U1, T2> type;
00229 };
00230 
00231 
00232 namespace pix_helper
00233 {
00234   // ######################################################################
00235   // ######################################################################
00236   // clamp and convert helpers
00237   // ######################################################################
00238   // ######################################################################
00239 
00240   /* These inline functions are used when setting Pix1 = Pix2 where the
00241      type for Pix1 is the same as Pix2, but its base type (float, int etc)
00242      is different.
00243 
00244      As examples:
00245      - PixRGB<float> A = PixRGB<byte> B            would use these.
00246      - PixRGB<float> A = PixHSV<int>  B            would NOT use these.
00247 
00248      Since the typing is uncertain in this usege we use clamped_convert for
00249      all copies
00250   */
00251 
00252   template <class pix1, class pix2>
00253   inline void clamped_assign_3(pix1& lhs, const pix2& rhs)
00254   {
00255     lhs.p[0] = clamped_convert<typename pix1::ScalarType>(rhs.p[0]);
00256     lhs.p[1] = clamped_convert<typename pix1::ScalarType>(rhs.p[1]);
00257     lhs.p[2] = clamped_convert<typename pix1::ScalarType>(rhs.p[2]);
00258   }
00259 
00260   template <class pix1, class pix2>
00261   inline void clamped_assign_4(pix1& lhs, const pix2& rhs)
00262   {
00263     lhs.p[0] = clamped_convert<typename pix1::ScalarType>(rhs.p[0]);
00264     lhs.p[1] = clamped_convert<typename pix1::ScalarType>(rhs.p[1]);
00265     lhs.p[2] = clamped_convert<typename pix1::ScalarType>(rhs.p[2]);
00266     lhs.p[3] = clamped_convert<typename pix1::ScalarType>(rhs.p[3]);
00267   }
00268 
00269   template <class pix1, class pix2>
00270   inline void clamped_assign_n(pix1& lhs, const pix2& rhs)
00271   {
00272     for (size_t i = 0; i < pix1::myDim; ++i)
00273       lhs.p[i] = clamped_convert<typename pix1::ScalarType>(rhs.p[i]);
00274   }
00275 
00276 
00277   // ######################################################################
00278   // ######################################################################
00279   // helper functions for defining operators
00280   // ######################################################################
00281   // ######################################################################
00282 
00283   // ######################################################################
00284   //! helper for adding a base type with a pixel where basic type T != T2
00285   /*! EXAMPLE: PixRGB<float> += int */
00286 
00287   template <class insttype, class T2, class functype>
00288   inline insttype& pix_scalar_op_eq(insttype& lhs,
00289                                     const T2 rhs,
00290                                     functype func)
00291   {
00292     typedef typename insttype::ScalarType T;
00293 
00294     for (size_t i = 0; i < insttype::myDim; i++)
00295       lhs.p[i] = clamped_convert<T>(func(lhs.p[i], rhs));
00296 
00297     return lhs;
00298   }
00299 
00300   // ######################################################################
00301   //! helper for adding a base type with a pixel where basic type T != T2
00302   /*! EXAMPLE: PixRGB<float> + int */
00303 
00304   template <class T, class insttype, class T2, class functype>
00305   inline typename rebind<insttype,
00306                          typename promote_trait<T, T2>::TP>::type
00307   pix_scalar_op(const insttype& lhs, const T2 rhs, functype func)
00308   {
00309     typedef typename promote_trait<T, T2>::TP TP;
00310     typename rebind<insttype, TP>::type result;
00311     for (size_t i = 0; i < insttype::myDim; i++)
00312       result.p[i] = clamped_convert<TP>(func(lhs.p[i], rhs));
00313     return result;
00314   }
00315 
00316   // ######################################################################
00317   //! Apply a x= operation between two pixels where the base type are the same
00318   /*! 4 operations can be performed here. The conditionals are constants so the compiler will pre-compute them
00319     (1) If a pixel type is the same and we will promote the trait and clamp         (e.g. PixRGB<byte>  += PixRGB<byte>  )
00320     (2) If a pixel type is not the same and we will promote the trait and clamp     (e.g. PixHSV<byte>  += PixRGB<byte>  )
00321     (3) If a pixel type is the same and we will not promote the trait and clamp     (e.g. PixRGB<float> += PixRGB<float> )
00322     (4) If a pixel type is not the same and we not will promote the trait and clamp (e.g. PixHSV<float> += PixRGB<float> )
00323   */
00324 
00325   template <class lhstype, class rhstype, class functype>
00326   inline lhstype& pix_pix_op_eq(lhstype& lhs,
00327                                 const rhstype& rhs,
00328                                 functype func)
00329   {
00330     ASSERT(lhs.pType == rhs.pType); // since both pixels are pixtype<>
00331 
00332     for (size_t i = 0; i < lhstype::myDim; i++)
00333       lhs.p[i] = clamped_convert<typename lhstype::ScalarType>
00334         (func(lhs.p[i], rhs.p[i]));
00335 
00336     return lhs;
00337   }
00338 
00339   // ######################################################################
00340   //! Apply a x operation between two pixels where the base type are the same
00341   /*! 2 operations can be performed here. The conditionals are constants so the compiler will pre-compute them
00342     (1) If a pixel type is the same and we will promote the trait      (e.g. PixRGB<byte> + PixRGB<byte> )
00343     (2) If a pixel type is not the same and we will promote the trait  (e.g. PixRGB<byte> + PixHSV<byte> )
00344   */
00345 
00346   template <template <class> class pixtype, class T, class T2, class functype>
00347   inline pixtype<typename promote_trait<T,T2>::TP>
00348   pix_pix_op(const pixtype<T>& lhs, const pixtype<T2>& rhs, functype func)
00349   {
00350     ASSERT(lhs.pType == rhs.pType); // since both pixels are pixtype<>
00351 
00352     typedef typename promote_trait<T,T2>::TP TP;
00353     pixtype<TP> result;
00354     for (size_t i = 0; i < pixtype<T>::myDim; i++)
00355       result.p[i] = clamped_convert<TP>(func(lhs.p[i], rhs.p[i]));
00356     return result;
00357   }
00358 
00359   template <template <class, size_t> class pixtype,
00360             class T, class T2, size_t dim, class functype>
00361   inline pixtype<typename promote_trait<T,T2>::TP, dim>
00362   pix_pix_op(const pixtype<T, dim>& lhs, const pixtype<T2, dim>& rhs, functype func)
00363   {
00364     ASSERT(lhs.pType == rhs.pType); // since both pixels are pixtype<>
00365 
00366     typedef typename promote_trait<T,T2>::TP TP;
00367     pixtype<TP, dim> result;
00368     for (size_t i = 0; i < pixtype<T, dim>::myDim; i++)
00369       result.p[i] = clamped_convert<TP>(func(lhs.p[i], rhs.p[i]));
00370     return result;
00371   }
00372 
00373 }
00374 
00375 //! A "mix-in" class that injects all arithmetic operators into the class that inherits it.
00376 /*! This is an example of "the curiously recurring template pattern",
00377     in which some class, say Foo, inherits from a template class
00378     instantiated on Foo, say Mixin<Foo>. In our case, we have the
00379     various pixel classes (e.g. PixRGB<T>) inheriting from this mixin
00380     class (e.g. pix_ops_mixin<PixRGB<T>, T>). */
00381 
00382 template <template <class> class pixtype, class T>
00383 struct pix_ops_mixin
00384 {
00385 
00386 #define PIX_MATH_OPS_EQ(OPSYM, FUNCTYPE)    \
00387   template <class T2> inline pixtype<T>& operator OPSYM (const pixtype<T2>& A) { return pix_helper::pix_pix_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); }
00388 
00389   PIX_MATH_OPS_EQ(+=, ops::plus)
00390   PIX_MATH_OPS_EQ(-=, ops::minus)
00391   PIX_MATH_OPS_EQ(*=, ops::multiplies)
00392   PIX_MATH_OPS_EQ(/=, ops::divides)
00393   PIX_MATH_OPS_EQ(%=, ops::modulo)
00394   PIX_MATH_OPS_EQ(&=, ops::bitwise_and)
00395   PIX_MATH_OPS_EQ(|=, ops::bitwise_or)
00396   PIX_MATH_OPS_EQ(^=, ops::bitwise_xor)
00397 
00398 #undef PIX_MATH_OPS_EQ
00399 
00400 #define PIX_OPERATOR_EQ(OPSYM, FUNCTYPE)                                                                                    \
00401   inline pixtype<T>& operator OPSYM (const bool           A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00402   inline pixtype<T>& operator OPSYM (const char           A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00403   inline pixtype<T>& operator OPSYM (const short          A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00404   inline pixtype<T>& operator OPSYM (const int            A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00405   inline pixtype<T>& operator OPSYM (const long           A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00406   inline pixtype<T>& operator OPSYM (const float          A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00407   inline pixtype<T>& operator OPSYM (const double         A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00408   inline pixtype<T>& operator OPSYM (const long double    A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00409   inline pixtype<T>& operator OPSYM (const unsigned char  A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00410   inline pixtype<T>& operator OPSYM (const unsigned short A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00411   inline pixtype<T>& operator OPSYM (const unsigned int   A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \
00412   inline pixtype<T>& operator OPSYM (const unsigned long  A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); }
00413 
00414   PIX_OPERATOR_EQ(+=, ops::plus)
00415   PIX_OPERATOR_EQ(-=, ops::minus)
00416   PIX_OPERATOR_EQ(*=, ops::multiplies)
00417   PIX_OPERATOR_EQ(/=, ops::divides)
00418   PIX_OPERATOR_EQ(%=, ops::modulo)
00419   PIX_OPERATOR_EQ(&=, ops::bitwise_and)
00420   PIX_OPERATOR_EQ(|=, ops::bitwise_or)
00421   PIX_OPERATOR_EQ(^=, ops::bitwise_xor)
00422 
00423 #undef PIX_OPERATOR_EQ
00424 
00425 #define PIX_MATH_OPS(OPSYM, FUNCTYPE)                                                           \
00426   template <class T2>                                                                           \
00427   inline typename rebind<pixtype<T>, typename promote_trait<T,T2>::TP>::type                    \
00428   operator OPSYM (const pixtype<T2>& rhs) const                                                 \
00429   { return pix_helper::pix_pix_op(static_cast<const pixtype<T>&>(*this), rhs, FUNCTYPE()); }
00430 
00431   PIX_MATH_OPS(+, ops::plus)
00432   PIX_MATH_OPS(-, ops::minus)
00433   PIX_MATH_OPS(*, ops::multiplies)
00434   PIX_MATH_OPS(/, ops::divides)
00435   PIX_MATH_OPS(%, ops::modulo)
00436   PIX_MATH_OPS(&, ops::bitwise_and)
00437   PIX_MATH_OPS(|, ops::bitwise_or)
00438   PIX_MATH_OPS(^, ops::bitwise_xor)
00439 
00440 #undef PIX_MATH_OPS
00441 
00442 #define PIX_OP(T2, OPSYM, FUNC)                                                                                                 \
00443   inline typename rebind<pixtype<T>, typename promote_trait<T, T2>::TP>::type                                                   \
00444   operator OPSYM (const T2 A) const { return pix_helper::pix_scalar_op<T>(static_cast<const pixtype<T>&>(*this), A, FUNC); }
00445 
00446 #define PIX_OPERATOR(OPSYM, FUNCTYPE)           \
00447   PIX_OP(bool, OPSYM, FUNCTYPE())               \
00448   PIX_OP(char, OPSYM, FUNCTYPE())               \
00449   PIX_OP(short, OPSYM, FUNCTYPE())              \
00450   PIX_OP(int, OPSYM, FUNCTYPE())                \
00451   PIX_OP(long, OPSYM, FUNCTYPE())               \
00452   PIX_OP(float, OPSYM, FUNCTYPE())              \
00453   PIX_OP(double, OPSYM, FUNCTYPE())             \
00454   PIX_OP(long double, OPSYM, FUNCTYPE())        \
00455   PIX_OP(unsigned char, OPSYM, FUNCTYPE())      \
00456   PIX_OP(unsigned short, OPSYM, FUNCTYPE())     \
00457   PIX_OP(unsigned int, OPSYM, FUNCTYPE())       \
00458   PIX_OP(unsigned long, OPSYM, FUNCTYPE())
00459 
00460   PIX_OPERATOR(+, ops::plus)
00461   PIX_OPERATOR(-, ops::minus)
00462   PIX_OPERATOR(*, ops::multiplies)
00463   PIX_OPERATOR(/, ops::divides)
00464   PIX_OPERATOR(%, ops::modulo)
00465   PIX_OPERATOR(&, ops::bitwise_and)
00466   PIX_OPERATOR(|, ops::bitwise_or)
00467   PIX_OPERATOR(^, ops::bitwise_xor)
00468 
00469 #undef PIX_OPERATOR
00470 #undef PIX_OP
00471 };
00472 
00473 template <template <class, size_t> class pixtype, class T, size_t dim>
00474 struct pix_ops_mixin_hyper
00475 {
00476 
00477 #define PIX_MATH_OPS_EQ(OPSYM, FUNCTYPE)                                                                                                                                            \
00478   template <class T2> inline pixtype<T, dim>& operator OPSYM (const pixtype<T2, dim>& A) { return pix_helper::pix_pix_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); }
00479 
00480   PIX_MATH_OPS_EQ(+=, ops::plus)
00481   PIX_MATH_OPS_EQ(-=, ops::minus)
00482   PIX_MATH_OPS_EQ(*=, ops::multiplies)
00483   PIX_MATH_OPS_EQ(/=, ops::divides)
00484   PIX_MATH_OPS_EQ(%=, ops::modulo)
00485   PIX_MATH_OPS_EQ(&=, ops::bitwise_and)
00486   PIX_MATH_OPS_EQ(|=, ops::bitwise_or)
00487   PIX_MATH_OPS_EQ(^=, ops::bitwise_xor)
00488 
00489 #undef PIX_MATH_OPS_EQ
00490 
00491 #define PIX_OPERATOR_EQ(OPSYM, FUNCTYPE)                                                                                    \
00492   inline pixtype<T, dim>& operator OPSYM (const bool           A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00493   inline pixtype<T, dim>& operator OPSYM (const char           A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00494   inline pixtype<T, dim>& operator OPSYM (const short          A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00495   inline pixtype<T, dim>& operator OPSYM (const int            A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00496   inline pixtype<T, dim>& operator OPSYM (const long           A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00497   inline pixtype<T, dim>& operator OPSYM (const float          A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00498   inline pixtype<T, dim>& operator OPSYM (const double         A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00499   inline pixtype<T, dim>& operator OPSYM (const long double    A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00500   inline pixtype<T, dim>& operator OPSYM (const unsigned char  A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00501   inline pixtype<T, dim>& operator OPSYM (const unsigned short A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00502   inline pixtype<T, dim>& operator OPSYM (const unsigned int   A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \
00503   inline pixtype<T, dim>& operator OPSYM (const unsigned long  A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); }
00504 
00505   PIX_OPERATOR_EQ(+=, ops::plus)
00506   PIX_OPERATOR_EQ(-=, ops::minus)
00507   PIX_OPERATOR_EQ(*=, ops::multiplies)
00508   PIX_OPERATOR_EQ(/=, ops::divides)
00509   PIX_OPERATOR_EQ(%=, ops::modulo)
00510   PIX_OPERATOR_EQ(&=, ops::bitwise_and)
00511   PIX_OPERATOR_EQ(|=, ops::bitwise_or)
00512   PIX_OPERATOR_EQ(^=, ops::bitwise_xor)
00513 
00514 #undef PIX_OPERATOR_EQ
00515 
00516 #define PIX_MATH_OPS(OPSYM, FUNCTYPE)                                                                   \
00517   template <class T2>                                                                                   \
00518   inline pixtype<typename promote_trait<T,T2>::TP, dim>                                                 \
00519   operator OPSYM (const pixtype<T2, dim>& rhs) const                                                    \
00520   { return pix_helper::pix_pix_op(static_cast<const pixtype<T, dim>&>(*this), rhs, FUNCTYPE()); }
00521 
00522   PIX_MATH_OPS(+, ops::plus)
00523   PIX_MATH_OPS(-, ops::minus)
00524   PIX_MATH_OPS(*, ops::multiplies)
00525   PIX_MATH_OPS(/, ops::divides)
00526   PIX_MATH_OPS(%, ops::modulo)
00527   PIX_MATH_OPS(&, ops::bitwise_and)
00528   PIX_MATH_OPS(|, ops::bitwise_or)
00529   PIX_MATH_OPS(^, ops::bitwise_xor)
00530 
00531 #undef PIX_MATH_OPS
00532 
00533 #define PIX_OP(T2, OPSYM, FUNC)                                                                                                         \
00534   inline typename rebind<pixtype<T, dim>, typename promote_trait<T, T2>::TP>::type                                                      \
00535   operator OPSYM (const T2 A) const { return pix_helper::pix_scalar_op<T>(static_cast<const pixtype<T, dim>&>(*this), A, FUNC); }
00536 
00537 #define PIX_OPERATOR(OPSYM, FUNCTYPE)           \
00538   PIX_OP(bool, OPSYM, FUNCTYPE())               \
00539   PIX_OP(char, OPSYM, FUNCTYPE())               \
00540   PIX_OP(short, OPSYM, FUNCTYPE())              \
00541   PIX_OP(int, OPSYM, FUNCTYPE())                \
00542   PIX_OP(long, OPSYM, FUNCTYPE())               \
00543   PIX_OP(float, OPSYM, FUNCTYPE())              \
00544   PIX_OP(double, OPSYM, FUNCTYPE())             \
00545   PIX_OP(long double, OPSYM, FUNCTYPE())        \
00546   PIX_OP(unsigned char, OPSYM, FUNCTYPE())      \
00547   PIX_OP(unsigned short, OPSYM, FUNCTYPE())     \
00548   PIX_OP(unsigned int, OPSYM, FUNCTYPE())       \
00549   PIX_OP(unsigned long, OPSYM, FUNCTYPE())
00550 
00551   PIX_OPERATOR(+, ops::plus)
00552   PIX_OPERATOR(-, ops::minus)
00553   PIX_OPERATOR(*, ops::multiplies)
00554   PIX_OPERATOR(/, ops::divides)
00555   PIX_OPERATOR(%, ops::modulo)
00556   PIX_OPERATOR(&, ops::bitwise_and)
00557   PIX_OPERATOR(|, ops::bitwise_or)
00558   PIX_OPERATOR(^, ops::bitwise_xor)
00559 
00560 #undef PIX_OPERATOR
00561 #undef PIX_OP
00562 };
00563 
00564 // #################################
00565 // #################################
00566 // ######################################################################
00567 // ######################################################################
00568 // --> PIXEL TYPE DECLARATIONS <--
00569 // ######################################################################
00570 // ######################################################################
00571 // #################################
00572 // #################################
00573 
00574 // ######################################################################
00575 // ######################################################################
00576 //! This is the basic RGB pixel class
00577 // ######################################################################
00578 // ######################################################################
00579 
00580 //! Derived RGB pixel class from Pixels
00581 template <class T> class PixRGB :
00582   public Pixels<T,3>,
00583   public pix_ops_mixin<PixRGB, T>
00584 {
00585 private:
00586 public:
00587   const static enum PixType pType = PixTypeRGB;
00588   const static size_t myDim = 3;
00589 
00590   using Pixels<T,3>::p;
00591 
00592   inline PixRGB();
00593   inline ~PixRGB();
00594   explicit inline PixRGB(const T val);
00595 
00596   template <class T2>
00597   explicit inline PixRGB(const T2 val);
00598 
00599   template <class T2> explicit inline PixRGB(const PixRGB<T2>&     A);
00600   template <class T2> explicit inline PixRGB(const PixHSV<T2>&     A);
00601   template <class T2> explicit inline PixRGB(const PixXYZ<T2>&     A);
00602   template <class T2> explicit inline PixRGB(const PixLab<T2>&     A);
00603   template <class T2> explicit inline PixRGB(const PixJpegYUV<T2>& A);
00604   template <class T2> explicit inline PixRGB(const PixVideoYUV<T2>& A);
00605   template <class T2> explicit inline PixRGB(const PixYIQ<T2>&     A);
00606   template <class T2> explicit inline PixRGB(const PixHSL<T2>&     A);
00607   template <class T2> explicit inline PixRGB(const PixH2SV1<T2>&   A);
00608   template <class T2> explicit inline PixRGB(const PixH2SV2<T2>&   A);
00609   template <class T2> explicit inline PixRGB(const PixHyper<T2,3>& A);
00610 
00611   // NOTE: default operator=() OK
00612 
00613   //! construct pixel from another. Defined here for tech reasons
00614   inline PixRGB(const PixRGB<T>& pix);
00615   //! Construct an RGB pixel with given values red, green, blue
00616   inline PixRGB(const T redval, const T greenval, const T blueval);
00617   //! Construct from given values, clamping & convertPixing as needed
00618   template <class T2, class T3, class T4> inline
00619   PixRGB(const T2 redval, const T3 greenval, const T4 blueval);
00620 
00621   // special local access methods
00622   inline void getRGB(T& r, T& g, T& b) const;
00623 
00624   //! Access red channel
00625   inline T red() const;
00626   //! Access green channel
00627   inline T green() const;
00628   //! Access blue channel
00629   inline T blue() const;
00630   //! Set red channel value, clamping & convertPixing as necessary
00631   template <class T2> inline void setRed(const T2 redval);
00632   //! Set green channel value, clamping & convertPixing as necessary
00633   template <class T2> inline void setGreen(const T2 greenval);
00634   //! Set blue channel value, clamping & convertPixing as necessary
00635   template <class T2> inline void setBlue(const T2 blueval);
00636   //! Set all channel values, clamping & convertPixing as necessary
00637   template <class T2, class T3, class T4> inline void
00638   set(const T2 redval, const T3 greenval, const T4 blueval);
00639   //! Compute luminance as (r + g + b) / 3
00640   inline T luminance() const;
00641   //! special methods added for backwards compat.
00642   inline void setHSV(const T h1, const T h2, const T s, const T v);
00643   //! special methods added for backwards compat.
00644   inline void getHSV(T& h1, T& h2, T& s, T& v) const;
00645 
00646   // Any overrides to Pixels methods
00647 
00648 };
00649 
00650 // ######################################################################
00651 // ######################################################################
00652 //! This is the basic HSV pixel class
00653 // ######################################################################
00654 // ######################################################################
00655 
00656 //! Derived HSV pixel class from Pixels
00657 template <class T> class PixHSV :
00658   public Pixels<T,3>,
00659   public pix_ops_mixin<PixHSV, T>
00660 {
00661 private:
00662 public:
00663   const static enum PixType pType = PixTypeHSV;
00664   const static size_t myDim = 3;
00665   using Pixels<T,3>::p;
00666 
00667   inline PixHSV();
00668   inline ~PixHSV();
00669   explicit inline PixHSV(const T val);
00670 
00671   template <class T2> explicit inline PixHSV(const PixRGB<T2>&     A);
00672   template <class T2> explicit inline PixHSV(const PixHSV<T2>&     A);
00673   template <class T2> explicit inline PixHSV(const PixYIQ<T2>&     A);
00674   template <class T2> explicit inline PixHSV(const PixHSL<T2>&     A);
00675   template <class T2> explicit inline PixHSV(const PixH2SV1<T2>&   A);
00676   template <class T2> explicit inline PixHSV(const PixH2SV2<T2>&   A);
00677   template <class T2> explicit inline PixHSV(const PixH2SV3<T2>&   A);
00678   template <class T2> explicit inline PixHSV(const PixHyper<T2,3>& A);
00679 
00680   // default operator=() OK
00681 
00682   //! construct pixel from another. Defined here for tech reasons
00683   inline PixHSV(const PixHSV<T>& pix);
00684   //! Construct an RGB pixel with given values red, green, blue
00685   inline PixHSV(const T Hval, const T Sval, const T Vval);
00686   //! Construct from given values, clamping & convertPixing as needed
00687   template <class T2, class T3, class T4> inline
00688   PixHSV(const T2 Hval, const T3 Sval, const T4 Vval);
00689 
00690   // special local methods
00691 
00692   inline void getHSV(T& h, T& s, T& v) const;
00693 
00694   //! Access hue channel
00695   inline T H() const;
00696   //! Access sat channel
00697   inline T S() const;
00698   //! Access val channel
00699   inline T V() const;
00700   //! Set hue channel value, clamping & converting as necessary
00701   template <class T2> inline void setH(const T2 H);
00702   //! Set sat channel value, clamping & converting as necessary
00703   template <class T2> inline void setS(const T2 S);
00704   //! Set val channel value, clamping & converting as necessary
00705   template <class T2> inline void setV(const T2 V);
00706 
00707   // Any overrides to Pixel methods
00708 };
00709 
00710 // ######################################################################
00711 // ######################################################################
00712 //! This is the basic jpeg-YUV pixel class
00713 // ######################################################################
00714 // ######################################################################
00715 
00716 //! Derived YUV pixel class from Pixels
00717 template <class T> class PixJpegYUV :
00718   public Pixels<T,3>,
00719   public pix_ops_mixin<PixJpegYUV, T>
00720 {
00721 private:
00722 public:
00723   const static enum PixType pType = PixTypeYUV;
00724   const static size_t myDim = 3;
00725   using Pixels<T,3>::p;
00726 
00727   inline PixJpegYUV();
00728   inline ~PixJpegYUV();
00729   explicit inline PixJpegYUV(const T val);
00730 
00731   template <class T2> explicit inline PixJpegYUV(const PixJpegYUV<T2>& A);
00732   template <class T2> explicit inline PixJpegYUV(const PixRGB<T2>&     A);
00733   template <class T2> explicit inline PixJpegYUV(const PixHyper<T2,3>& A);
00734 
00735   // default operator=() OK
00736 
00737   inline PixJpegYUV(const PixJpegYUV<T>& pix);
00738 
00739   //! Construct an RGB pixel with given values red, green, blue
00740   inline PixJpegYUV(const T Yval, const T Uval, const T Vval);
00741   //! Construct from given values, clamping & converting as needed
00742   template <class T2, class T3, class T4> inline
00743   PixJpegYUV(const T2 Yval, const T3 Uval, const T4 Vval);
00744 
00745   //! Access Y channel
00746   inline T Y() const;
00747   //! Access U channel
00748   inline T U() const;
00749   //! Access V channel
00750   inline T V() const;
00751   //! Set Y channel value, clamping & converting as necessary
00752   template <class T2> inline void setY(const T2 Y);
00753   //! Set U channel value, clamping & converting as necessary
00754   template <class T2> inline void setU(const T2 U);
00755   //! Set V channel value, clamping & converting as necessary
00756   template <class T2> inline void setV(const T2 V);
00757 
00758   // Any overrides to Pixel methods
00759 };
00760 
00761 // ######################################################################
00762 // ######################################################################
00763 //! This is the basic video-YUV pixel class
00764 // ######################################################################
00765 // ######################################################################
00766 
00767 //! Derived YUV pixel class from Pixels
00768 template <class T> class PixVideoYUV :
00769   public Pixels<T,3>,
00770   public pix_ops_mixin<PixVideoYUV, T>
00771 {
00772 private:
00773 public:
00774   const static enum PixType pType = PixTypeYUV;
00775   const static size_t myDim = 3;
00776   using Pixels<T,3>::p;
00777 
00778   inline PixVideoYUV();
00779   inline ~PixVideoYUV();
00780   explicit inline PixVideoYUV(const T val);
00781 
00782   template <class T2> explicit inline PixVideoYUV(const PixVideoYUV<T2>& A);
00783   template <class T2> explicit inline PixVideoYUV(const PixRGB<T2>&     A);
00784   template <class T2> explicit inline PixVideoYUV(const PixHyper<T2,3>& A);
00785 
00786   // default operator=() OK
00787 
00788   inline PixVideoYUV(const PixVideoYUV<T>& pix);
00789 
00790   //! Construct an RGB pixel with given values red, green, blue
00791   inline PixVideoYUV(const T Yval, const T Uval, const T Vval);
00792   //! Construct from given values, clamping & converting as needed
00793   template <class T2, class T3, class T4> inline
00794   PixVideoYUV(const T2 Yval, const T3 Uval, const T4 Vval);
00795 
00796   // special local methods
00797 
00798   inline void getVideoYUV(T& y, T& u, T& v) const;
00799 
00800   //! Access Y channel
00801   inline T Y() const;
00802   //! Access U channel
00803   inline T U() const;
00804   //! Access V channel
00805   inline T V() const;
00806   //! Set Y channel value, clamping & converting as necessary
00807   template <class T2> inline void setY(const T2 Y);
00808   //! Set U channel value, clamping & converting as necessary
00809   template <class T2> inline void setU(const T2 U);
00810   //! Set V channel value, clamping & converting as necessary
00811   template <class T2> inline void setV(const T2 V);
00812 
00813   // Any overrides to Pixel methods
00814 };
00815 
00816 // ######################################################################
00817 // ######################################################################
00818 //! This is the basic YIQ pixel class
00819 // ######################################################################
00820 // ######################################################################
00821 
00822 //! Derived YIQ pixel class from Pixels
00823 template <class T> class PixYIQ :
00824   public Pixels<T,3>,
00825   public pix_ops_mixin<PixYIQ, T>
00826 {
00827 private:
00828 public:
00829   const static enum PixType pType = PixTypeYIQ;
00830   const static size_t myDim = 3;
00831   using Pixels<T,3>::p;
00832 
00833   inline PixYIQ();
00834   inline ~PixYIQ();
00835   explicit inline PixYIQ(const T val);
00836 
00837   template <class T2> explicit inline PixYIQ(const PixRGB<T2>&     A);
00838   template <class T2> explicit inline PixYIQ(const PixHSV<T2>&     A);
00839   template <class T2> explicit inline PixYIQ(const PixYIQ<T2>&     A);
00840   template <class T2> explicit inline PixYIQ(const PixHSL<T2>&     A);
00841   template <class T2> explicit inline PixYIQ(const PixH2SV1<T2>&   A);
00842   template <class T2> explicit inline PixYIQ(const PixH2SV2<T2>&   A);
00843   template <class T2> explicit inline PixYIQ(const PixH2SV3<T2>&   A);
00844   template <class T2> explicit inline PixYIQ(const PixHyper<T2,3>& A);
00845 
00846   // default operator=() OK
00847 
00848   //! construct pixel from another. Defined here for tech reasons
00849   inline PixYIQ(const PixYIQ<T>& pix);
00850   //! Construct an RGB pixel with given values red, green, blue
00851   inline PixYIQ(const T Yval, const T Ival, const T Qval);
00852   //! Construct from given values, clamping & converting as needed
00853   template <class T2, class T3, class T4> inline
00854   PixYIQ(const T2 Yval, const T3 Uval, const T4 Vval);
00855 
00856   // special local methods
00857 
00858   inline void getYIQ(T& y, T& i, T& q) const;
00859 
00860   //! Access Y channel
00861   inline T Y() const;
00862   //! Access I channel
00863   inline T I() const;
00864   //! Access Q channel
00865   inline T Q() const;
00866   //! Set Y channel value, clamping & converting as necessary
00867   template <class T2> inline void setY(const T2 Y);
00868   //! Set I channel value, clamping & converting as necessary
00869   template <class T2> inline void setI(const T2 I);
00870   //! Set Q channel value, clamping & converting as necessary
00871   template <class T2> inline void setQ(const T2 Q);
00872 
00873   // Any overrides to Pixel methods
00874 };
00875 
00876 // ######################################################################
00877 // ######################################################################
00878 //! This is the basic HSL pixel class
00879 // ######################################################################
00880 // ######################################################################
00881 
00882 //! Derived HSL pixel class from Pixels
00883 template <class T> class PixHSL :
00884   public Pixels<T,3>,
00885   public pix_ops_mixin<PixHSL, T>
00886 {
00887 private:
00888 public:
00889   const static enum PixType pType = PixTypeHSL;
00890   const static size_t myDim = 3;
00891   using Pixels<T,3>::p;
00892 
00893   inline PixHSL();
00894   inline ~PixHSL();
00895   explicit inline PixHSL(const T val);
00896 
00897   template <class T2> explicit inline PixHSL(const PixRGB<T2>&     A);
00898   template <class T2> explicit inline PixHSL(const PixHSV<T2>&     A);
00899   template <class T2> explicit inline PixHSL(const PixYIQ<T2>&     A);
00900   template <class T2> explicit inline PixHSL(const PixHSL<T2>&     A);
00901   template <class T2> explicit inline PixHSL(const PixH2SV1<T2>&   A);
00902   template <class T2> explicit inline PixHSL(const PixH2SV2<T2>&   A);
00903   template <class T2> explicit inline PixHSL(const PixH2SV3<T2>&   A);
00904   template <class T2> explicit inline PixHSL(const PixHyper<T2,3>& A);
00905 
00906   // default operator=() OK
00907 
00908   //! construct pixel from another. Defined here for tech reasons
00909   inline PixHSL(const PixHSL<T>& pix);
00910   //! Construct an RGB pixel with given values red, green, blue
00911   inline PixHSL(const T Hval, const T Sval, const T Lval);
00912   //! Construct from given values, clamping & convertPixing as needed
00913   template <class T2, class T3, class T4> inline
00914   PixHSL(const T2 Hval, const T3 Sval, const T4 Lval);
00915 
00916   // special local methods
00917 
00918   inline void getHSL(T& h, T& s, T& l) const;
00919 
00920   //! Access hue channel
00921   inline T H() const;
00922   //! Access sat channel
00923   inline T S() const;
00924   //! Access val channel
00925   inline T L() const;
00926   //! Set hue channel value, clamping & converting as necessary
00927   template <class T2> inline void setH(const T2 H);
00928   //! Set sat channel value, clamping & converting as necessary
00929   template <class T2> inline void setS(const T2 S);
00930   //! Set val channel value, clamping & converting as necessary
00931   template <class T2> inline void setL(const T2 L);
00932 
00933   // Any overrides to Pixel methods
00934 };
00935 
00936 // ######################################################################
00937 // ######################################################################
00938 //! This is the basic Lab pixel class
00939 // ######################################################################
00940 // ######################################################################
00941 
00942 //! Derived Lab pixel class from Pixels
00943 template <class T> class PixLab :
00944   public Pixels<T,3>,
00945   public pix_ops_mixin<PixLab, T>
00946 {
00947 private:
00948 public:
00949   const static enum PixType pType = PixTypeLab;
00950   const static size_t myDim = 3;
00951   using Pixels<T,3>::p;
00952 
00953   inline PixLab();
00954   inline ~PixLab();
00955   explicit inline PixLab(const T val);
00956 
00957   template <class T2> explicit inline PixLab(const PixRGB<T2>&     A);
00958   template <class T2> explicit inline PixLab(const PixLab<T2>&     A);
00959   template <class T2> explicit inline PixLab(const PixHyper<T2,3>& A);
00960 
00961   // default operator=() OK
00962 
00963   //! construct pixel from another. Defined here for tech reasons
00964   inline PixLab(const PixLab<T>& pix);
00965   //! Construct an RGB pixel with given values red, green, blue
00966   inline PixLab(const T Lval, const T Aval, const T Bval);
00967   //! Construct from given values, clamping & convertPixing as needed
00968   template <class T2, class T3, class T4> inline
00969   PixLab(const T2 Lval, const T3 Aval, const T4 Bval);
00970 
00971   // special local methods
00972 
00973   inline void getLab(T& l, T& a, T& b) const;
00974 
00975   //! Access hue channel
00976   inline T L() const;
00977   //! Access sat channel
00978   inline T A() const;
00979   //! Access val channel
00980   inline T B() const;
00981   //! Set hue channel value, clamping & converting as necessary
00982   template <class T2> inline void setL(const T2 L);
00983   //! Set sat channel value, clamping & converting as necessary
00984   template <class T2> inline void setA(const T2 A);
00985   //! Set val channel value, clamping & converting as necessary
00986   template <class T2> inline void setB(const T2 B);
00987 
00988   // Any overrides to Pixel methods
00989 };
00990 
00991 // ######################################################################
00992 // ######################################################################
00993 //! This is the basic XYZ pixel class
00994 // ######################################################################
00995 // ######################################################################
00996 
00997 //! Derived XYZ pixel class from Pixels
00998 template <class T> class PixXYZ :
00999   public Pixels<T,3>,
01000   public pix_ops_mixin<PixXYZ, T>
01001 {
01002 private:
01003 public:
01004   const static enum PixType pType = PixTypeXYZ;
01005   const static size_t myDim = 3;
01006   using Pixels<T,3>::p;
01007 
01008   inline PixXYZ();
01009   inline ~PixXYZ();
01010   explicit inline PixXYZ(const T val);
01011 
01012   template <class T2> explicit inline PixXYZ(const PixRGB<T2>&     A);
01013   template <class T2> explicit inline PixXYZ(const PixXYZ<T2>&     A);
01014   template <class T2> explicit inline PixXYZ(const PixHyper<T2,3>& A);
01015 
01016   // default operator=() OK
01017 
01018   //! construct pixel from another. Defined here for tech reasons
01019   inline PixXYZ(const PixXYZ<T>& pix);
01020   //! Construct an RGB pixel with given values red, green, blue
01021   inline PixXYZ(const T Xval, const T Yval, const T Zval);
01022   //! Construct from given values, clamping & convertPixing as needed
01023   template <class T2, class T3, class T4> inline
01024   PixXYZ(const T2 Xval, const T3 Yval, const T4 Zval);
01025 
01026   // special local methods
01027 
01028   inline void getXYZ(T& x, T& y, T& z) const;
01029 
01030   //! Access hue channel
01031   inline T X() const;
01032   //! Access sat channel
01033   inline T Y() const;
01034   //! Access val channel
01035   inline T Z() const;
01036   //! Set hue channel value, clamping & converting as necessary
01037   template <class T2> inline void setX(const T2 X);
01038   //! Set sat channel value, clamping & converting as necessary
01039   template <class T2> inline void setY(const T2 Y);
01040   //! Set val channel value, clamping & converting as necessary
01041   template <class T2> inline void setZ(const T2 Z);
01042 
01043   // Any overrides to Pixel methods
01044 };
01045 
01046 // ######################################################################
01047 // ######################################################################
01048 //! This is the H2SV1 pixel class
01049 /*! This is the HSV color space normalized and de-modulized into
01050     components H1 H2 S and V. This is used since the modulus nature
01051     of hue makes it hard to deal with in many types of computation.
01052     PixH2SV1 is a very linear transforamtion.
01053     PixH2SV2 is linear but is B/Y R/G opponent in nature
01054     PixH2SV3 is as bio as this can get but is less linear
01055 */
01056 // ######################################################################
01057 // ######################################################################
01058 
01059 //! Derived H2SV1 pixel class from Pixels
01060 template <class T> class PixH2SV1 :
01061   public Pixels<T,4>,
01062   public pix_ops_mixin<PixH2SV1, T>
01063 {
01064 private:
01065 public:
01066   const static enum PixType pType = PixTypeH2SV1;
01067   const static size_t myDim = 4;
01068   using Pixels<T,4>::p;
01069 
01070   inline PixH2SV1();
01071   inline ~PixH2SV1();
01072   explicit inline PixH2SV1(const T val);
01073 
01074   template <class T2> explicit inline PixH2SV1(const PixRGB<T2>&     A);
01075   template <class T2> explicit inline PixH2SV1(const PixHSV<T2>&     A);
01076   template <class T2> explicit inline PixH2SV1(const PixYIQ<T2>&     A);
01077   template <class T2> explicit inline PixH2SV1(const PixHSL<T2>&     A);
01078   template <class T2> explicit inline PixH2SV1(const PixH2SV1<T2>&   A);
01079   template <class T2> explicit inline PixH2SV1(const PixH2SV2<T2>&   A);
01080   template <class T2> explicit inline PixH2SV1(const PixH2SV3<T2>&   A);
01081   template <class T2> explicit inline PixH2SV1(const PixHyper<T2,4>& A);
01082 
01083   // default operator=() OK
01084 
01085   //! construct pixel from another. Defined here for tech reasons
01086   inline PixH2SV1(const PixH2SV1<T>& pix);
01087   //! Construct an RGB pixel with given values red, green, blue
01088   inline PixH2SV1(const T H1val, const T H2val, const T Sval, const T Vval);
01089   //! Construct from given values, clamping & converting as needed
01090   template <class T2, class T3, class T4, class T5> inline
01091   PixH2SV1(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval );
01092 
01093   // special local methods
01094   inline void getH2SV1(T& h1, T& h2, T& s, T& v) const;
01095 
01096   //! Access H1 channel
01097   inline T H1() const;
01098   //! Access H2 channel
01099   inline T H2() const;
01100   //! Access S channel
01101   inline T S() const;
01102   //! Access V channel
01103   inline T V() const;
01104   //! Set H1 channel value, clamping & converting as necessary
01105   template <class T2> inline void setH1(const T2 H1);
01106   //! Set H2 channel value, clamping & converting as necessary
01107   template <class T2> inline void setH2(const T2 H2);
01108   //! Set S channel value, clamping & converting as necessary
01109   template <class T2> inline void setS(const T2 S);
01110   //! Set V channel value, clamping & converting as necessary
01111   template <class T2> inline void setV(const T2 V);
01112 
01113   // Any overrides to Pixel methods
01114 };
01115 
01116 // ######################################################################
01117 // ######################################################################
01118 //! This is the H2SV2 pixel class
01119 /*! This is the HSV color space normalized and de-modulized into
01120     components H1 H2 S and V. This is used since the modulus nature
01121     of hue makes it hard to deal with in many types of computation.
01122     PixH2SV1 is a very linear transforamtion.
01123     PixH2SV2 is linear but is B/Y R/G opponent in nature
01124     PixH2SV3 is as bio as this can get but is less linear
01125 */
01126 // ######################################################################
01127 // ######################################################################
01128 
01129 //! Derived H2SV2 pixel class from Pixels
01130 template <class T> class PixH2SV2 :
01131   public Pixels<T,4>,
01132   public pix_ops_mixin<PixH2SV2, T>
01133 {
01134 private:
01135 public:
01136   const static enum PixType pType = PixTypeH2SV2;
01137   const static size_t myDim = 4;
01138   using Pixels<T,4>::p;
01139 
01140   inline PixH2SV2();
01141   inline ~PixH2SV2();
01142   explicit inline PixH2SV2(const T val);
01143 
01144   template <class T2> explicit inline PixH2SV2(const PixRGB<T2>&     A);
01145   template <class T2> explicit inline PixH2SV2(const PixHSV<T2>&     A);
01146   template <class T2> explicit inline PixH2SV2(const PixYIQ<T2>&     A);
01147   template <class T2> explicit inline PixH2SV2(const PixHSL<T2>&     A);
01148   template <class T2> explicit inline PixH2SV2(const PixH2SV1<T2>&   A);
01149   template <class T2> explicit inline PixH2SV2(const PixH2SV2<T2>&   A);
01150   template <class T2> explicit inline PixH2SV2(const PixH2SV3<T2>&   A);
01151   template <class T2> explicit inline PixH2SV2(const PixHyper<T2,4>& A);
01152 
01153   // default operator=() OK
01154 
01155   //! construct pixel from another. Defined here for tech reasons
01156   inline PixH2SV2(const PixH2SV2<T>& pix);
01157   //! Construct an RGB pixel with given values red, green, blue
01158   inline PixH2SV2(const T H1val, const T H2val, const T Sval, const T Vval);
01159   //! Construct from given values, clamping & converting as needed
01160   template <class T2, class T3, class T4, class T5> inline
01161   PixH2SV2(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval );
01162 
01163   // special local methods
01164 
01165   inline void getH2SV2(T& h1, T& h2, T& s, T& v) const;
01166 
01167   //! Access H1 channel
01168   inline T H1() const;
01169   //! Access H2 channel
01170   inline T H2() const;
01171   //! Access S channel
01172   inline T S() const;
01173   //! Access V channel
01174   inline T V() const;
01175   //! Set H1 channel value, clamping & converting as necessary
01176   template <class T2> inline void setH1(const T2 H1);
01177   //! Set H2 channel value, clamping & converting as necessary
01178   template <class T2> inline void setH2(const T2 H2);
01179   //! Set S channel value, clamping & converting as necessary
01180   template <class T2> inline void setS(const T2 S);
01181   //! Set V channel value, clamping & converting as necessary
01182   template <class T2> inline void setV(const T2 V);
01183 
01184   // Any overrides to Pixel methods
01185 };
01186 
01187 // ######################################################################
01188 // ######################################################################
01189 //! This is the H2SV3 pixel class
01190 /*! This is the HSV color space normalized and de-modulized into
01191     components H1 H2 S and V. This is used since the modulus nature
01192     of hue makes it hard to deal with in many types of computation.
01193     PixH2SV1 is a very linear transforamtion.
01194     PixH2SV2 is linear but is B/Y R/G opponent in nature
01195     PixH2SV3 is as bio as this can get but is less linear
01196 */
01197 // ######################################################################
01198 // ######################################################################
01199 
01200 //! Derived H2SV3 pixel class from Pixels
01201 template <class T> class PixH2SV3 :
01202   public Pixels<T,4>,
01203   public pix_ops_mixin<PixH2SV3, T>
01204 {
01205 private:
01206 public:
01207   const static enum PixType pType = PixTypeH2SV3;
01208   const static size_t myDim = 4;
01209   using Pixels<T,4>::p;
01210 
01211   inline PixH2SV3();
01212   inline ~PixH2SV3();
01213   explicit inline PixH2SV3(const T val);
01214 
01215   template <class T2> explicit inline PixH2SV3(const PixYIQ<T2>&     A);
01216   template <class T2> explicit inline PixH2SV3(const PixH2SV1<T2>&   A);
01217   template <class T2> explicit inline PixH2SV3(const PixH2SV2<T2>&   A);
01218   template <class T2> explicit inline PixH2SV3(const PixH2SV3<T2>&   A);
01219   template <class T2> explicit inline PixH2SV3(const PixHyper<T2,4>& A);
01220 
01221   // default operator=() OK
01222 
01223   //! construct pixel from another. Defined here for tech reasons
01224   inline PixH2SV3(const PixH2SV3<T>& pix);
01225   //! Construct an RGB pixel with given values red, green, blue
01226   inline PixH2SV3(const T H1val, const T H2val, const T Sval, const T Vval);
01227   //! Construct from given values, clamping & converting as needed
01228   template <class T2, class T3, class T4, class T5> inline
01229   PixH2SV3(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval );
01230 
01231   // special local methods
01232 
01233   inline void getH2SV3(T& h1, T& h2, T& s, T& v) const;
01234 
01235   //! Access H1 channel
01236   inline T H1() const;
01237   //! Access H2 channel
01238   inline T H2() const;
01239   //! Access S channel
01240   inline T S() const;
01241   //! Access V channel
01242   inline T V() const;
01243   //! Set H1 channel value, clamping & converting as necessary
01244   template <class T2> inline void setH1(const T2 H1);
01245   //! Set H2 channel value, clamping & converting as necessary
01246   template <class T2> inline void setH2(const T2 H2);
01247   //! Set S channel value, clamping & converting as necessary
01248   template <class T2> inline void setS(const T2 S);
01249   //! Set V channel value, clamping & converting as necessary
01250   template <class T2> inline void setV(const T2 V);
01251 
01252   // Any overrides to Pixel methods
01253 };
01254 
01255 // ######################################################################
01256 // ######################################################################
01257 //! This is the hyper pixel class
01258 // ######################################################################
01259 // ######################################################################
01260 
01261 //! Derived Hyper spectral pixel class from Pixels
01262 template <class T, size_t dim> class PixHyper :
01263   public Pixels<T,dim>,
01264   public pix_ops_mixin_hyper<PixHyper, T, dim>
01265 {
01266 private:
01267 public:
01268   const static enum PixType pType = PixTypeHyper;
01269   const static size_t myDim = dim;
01270 
01271   using Pixels<T,dim>::p;
01272 
01273   inline PixHyper();
01274   inline ~PixHyper();
01275   explicit inline PixHyper(const T val);
01276 
01277   template <class T2> explicit inline PixHyper(const PixRGB<T2>&     A);
01278   template <class T2> explicit inline PixHyper(const PixHSV<T2>&     A);
01279   template <class T2> explicit inline PixHyper(const PixJpegYUV<T2>& A);
01280   template <class T2> explicit inline PixHyper(const PixVideoYUV<T2>& A);
01281   template <class T2> explicit inline PixHyper(const PixYIQ<T2>&     A);
01282   template <class T2> explicit inline PixHyper(const PixHSL<T2>&     A);
01283   template <class T2> explicit inline PixHyper(const PixH2SV1<T2>&   A);
01284   template <class T2> explicit inline PixHyper(const PixH2SV2<T2>&   A);
01285   template <class T2> explicit inline PixHyper(const PixH2SV3<T2>&   A);
01286   template <class T2> explicit inline PixHyper(const PixHyper<T2,dim>& A);
01287 
01288   //! construct pixel from another. Defined here for tech reasons
01289   inline PixHyper(const PixHyper<T,dim>& pix);
01290 };
01291 
01292 // ######################################################################
01293 // ######################################################################
01294 //! This is the basic DKL pixel class
01295 // ######################################################################
01296 // ######################################################################
01297 
01298 //! Derived DKL pixel class from Pixels
01299 template <class T> class PixDKL :
01300   public Pixels<T,3>,
01301   public pix_ops_mixin<PixDKL, T>
01302 {
01303 private:
01304 public:
01305   const static enum PixType pType = PixTypeDKL;
01306   const static size_t myDim = 3;
01307   using Pixels<T,3>::p;
01308 
01309   inline PixDKL();
01310   inline ~PixDKL();
01311   explicit inline PixDKL(const T val);
01312 
01313   template <class T2> explicit inline PixDKL(const PixRGB<T2>&     A);
01314   template <class T2> explicit inline PixDKL(const PixDKL<T2>&     A);
01315 
01316   // default operator=() OK
01317 
01318   //! construct pixel from another. Defined here for tech reasons
01319   inline PixDKL(const PixDKL<T>& pix);
01320   //! Construct a pixel with given values for D, K, L
01321   inline PixDKL(const T Dval, const T Kval, const T Lval);
01322   //! Construct from given values, clamping & convertPixing as needed
01323   template <class T2, class T3, class T4> inline
01324   PixDKL(const T2 Dval, const T3 Kval, const T4 Lval);
01325 
01326   // special local methods
01327 
01328   inline void getDKL(T& d, T& k, T& l) const;
01329 
01330   //! Access hue channel
01331   inline T D() const;
01332   //! Access sat channel
01333   inline T K() const;
01334   //! Access val channel
01335   inline T L() const;
01336   //! Set hue channel value, clamping & converting as necessary
01337   template <class T2> inline void setD(const T2 D);
01338   //! Set sat channel value, clamping & converting as necessary
01339   template <class T2> inline void setK(const T2 K);
01340   //! Set val channel value, clamping & converting as necessary
01341   template <class T2> inline void setL(const T2 L);
01342 
01343   // Any overrides to Pixel methods
01344 };
01345 
01346 // #################################
01347 // #################################
01348 // ######################################################################
01349 // ######################################################################
01350 // --> PIXEL METHODS <--
01351 // ######################################################################
01352 // ######################################################################
01353 // #################################
01354 // #################################
01355 
01356 // ######################################################################
01357 // ######################################################################
01358 // Pixels RGB
01359 // ######################################################################
01360 // ######################################################################
01361 
01362 // ######################################################################
01363 // constructors for where Pix<T> != Pix<T2> - with conversion
01364 // ######################################################################
01365 
01366 template <class T>
01367 template <class T2> inline PixRGB<T>::PixRGB(const PixRGB<T2>& A)
01368   : Pixels<T,3>()
01369 {
01370   pix_helper::clamped_assign_3(*this, A);
01371 }
01372 
01373 // ######################################################################
01374 template <class T>
01375 template <class T2> inline PixRGB<T>::PixRGB(const PixHSV<T2>& A1)
01376   : Pixels<T,3>()
01377 {
01378   const PixHSV<double> A( A1 );
01379 
01380   // p[0] = r : p[1] = g : p[2] = b
01381   // A[0] = h : A[1] = s : A[2] = v
01382 
01383   const double vf = A[2] / HSV_V_UPPER;
01384   const double sf = A[1] / HSV_S_UPPER;
01385 
01386 // SEE PixelsCommonDef.H
01387 PIX_HSV_TO_RGB_COMMON(A[0],sf,vf,p[0],p[1],p[2])
01388 
01389 }
01390 
01391 // ######################################################################
01392 template <class T>
01393 template <class T2> inline PixRGB<T>::PixRGB(const PixXYZ<T2>& A1)
01394   : Pixels<T,3>()
01395 {
01396   const PixXYZ<double> A( A1 );
01397 
01398   // p[0] = r : p[1] = g : p[2] = b
01399   // A[0] = x : A[1] = y : A[2] = z
01400 
01401 // SEE PixelsCommonDef.H
01402   double r,g,b;
01403 
01404 PIX_XYZ_TO_RGB_OPENCV_COMMON(A[0],A[1],A[2],r,g,b)
01405 
01406   p[0] = clamped_convert<T>(r);
01407   p[1] = clamped_convert<T>(g);
01408   p[2] = clamped_convert<T>(b);
01409 }
01410 
01411 // ######################################################################
01412 template <class T>
01413 template <class T2> inline PixRGB<T>::PixRGB(const PixLab<T2>& A1)
01414   : Pixels<T,3>()
01415 {
01416   const PixLab<double> A( A1 );
01417 
01418   // p[0] = r : p[1] = g : p[2] = b
01419   // A[0] = l : A[1] = a : A[2] = b
01420 
01421   double X,Y,Z,r,g,b;
01422 
01423 // SEE PixelsCommonDef.H
01424 PIX_LAB_TO_XYZ_OPENCV_COMMON(A[0],A[1],A[2],X,Y,Z)
01425 // SEE PixelsCommonDef.H
01426 PIX_XYZ_TO_RGB_OPENCV_COMMON(X,Y,Z,r,g,b)
01427 
01428   p[0] = clamped_convert<T>(r);
01429   p[1] = clamped_convert<T>(g);
01430   p[2] = clamped_convert<T>(b);
01431 }
01432 
01433 // ######################################################################
01434 template <class T>
01435 template <class T2> inline PixRGB<T>::PixRGB(const PixJpegYUV<T2>& A)
01436   : Pixels<T,3>()
01437 {
01438   // p[0] = r : p[1] = g : p[2] = b
01439   // A[0] = y : A[1] = u : A[2] = v
01440   const double yf = double(A[0]) - JPEGYUV_Y_OFFSET;
01441   const double uf = double(A[1]) - JPEGYUV_UV_OFFSET;
01442   const double vf = double(A[2]) - JPEGYUV_UV_OFFSET;
01443 
01444   const double rf = yf                  + JPEGYUV_R_V*vf;
01445   const double gf = yf + JPEGYUV_G_U*uf + JPEGYUV_G_V*vf;
01446   const double bf = yf + JPEGYUV_B_U*uf;
01447 
01448   this->p[0] = clamped_rounded_convert<T>(clampValue(rf, 0.0, 255.0));
01449   this->p[1] = clamped_rounded_convert<T>(clampValue(gf, 0.0, 255.0));
01450   this->p[2] = clamped_rounded_convert<T>(clampValue(bf, 0.0, 255.0));
01451 }
01452 
01453 // ######################################################################
01454 template <class T>
01455 template <class T2> inline PixRGB<T>::PixRGB(const PixVideoYUV<T2>& A)
01456   : Pixels<T,3>()
01457 {
01458   // p[0] = r : p[1] = g : p[2] = b
01459   // A[0] = y : A[1] = u : A[2] = v
01460   const double yf = double(A[0]) - VIDEOYUV_Y_OFFSET;
01461   const double uf = double(A[1]) - VIDEOYUV_UV_OFFSET;
01462   const double vf = double(A[2]) - VIDEOYUV_UV_OFFSET;
01463 
01464   const double rf = VIDEOYUV_RGB_Y*yf                   + VIDEOYUV_R_V*vf;
01465   const double gf = VIDEOYUV_RGB_Y*yf + VIDEOYUV_G_U*uf + VIDEOYUV_G_V*vf;
01466   const double bf = VIDEOYUV_RGB_Y*yf + VIDEOYUV_B_U*uf;
01467 
01468   this->p[0] = clamped_rounded_convert<T>(clampValue(rf, 0.0, 255.0));
01469   this->p[1] = clamped_rounded_convert<T>(clampValue(gf, 0.0, 255.0));
01470   this->p[2] = clamped_rounded_convert<T>(clampValue(bf, 0.0, 255.0));
01471 }
01472 
01473 // ######################################################################
01474 template <class T>
01475 template <class T2> inline PixRGB<T>::PixRGB(const PixYIQ<T2>& A1)
01476   : Pixels<T,3>()
01477 {
01478   const PixYIQ<double> A( A1 );
01479 
01480   // p[0] = r : p[1] = g : p[2] = b
01481   // A[0] = y : A[1] = i : A[2] = q
01482   p[0] = clamped_rounded_convert<T>(1.0 * A[0] + 0.956 * A[1] + 0.621 * A[2]);
01483   p[1] = clamped_rounded_convert<T>(1.0 * A[0] - 0.272 * A[1] - 0.647 * A[2]);
01484   p[2] = clamped_rounded_convert<T>(1.0 * A[0] - 1.105 * A[1] + 1.702 * A[2]);
01485 }
01486 
01487 // ######################################################################
01488 template <class T>
01489 template <class T2> inline PixRGB<T>::PixRGB(const PixHSL<T2>& A1)
01490   : Pixels<T,3>()
01491 {
01492   const PixHSL<double> A( A1 );
01493 
01494   // p[0] = r : p[1] = g : p[2] = b
01495   // A[0] = h : A[1] = s : A[2] = l
01496   const double H = A[0];
01497   const double S = A[1];
01498   const double L = A[2];
01499 
01500   if(S == 0)
01501   {
01502     p[0] = clamped_convert<T>(L*RGB_R_UPPER);
01503     p[1] = clamped_convert<T>(L*RGB_G_UPPER);
01504     p[2] = clamped_convert<T>(L*RGB_B_UPPER);
01505   }
01506   else
01507   {
01508     double r,g,b;
01509     double t2;
01510     if(L < 0.5) t2 = L * (1.0 + S);
01511     else        t2 = L + S - (L * S);
01512     const double t1 = 2.0 * L - t2;
01513     const double hk = H/360;
01514 
01515     // Set RED
01516     const double tr = hk + 1.0/3.0;
01517     if      (tr < 0) tr = tr + 1;
01518     else if (tr > 1) tr = tr - 1;
01519     if      (tr < 1.0/6.0) r = t1 + ((t2 - t1) * 6.0 * tr);
01520     else if (tr < 1.0/2.0) r = t2;
01521     else if (tr < 2.0/3.0) r = t1 + ((t2 - t1) * 6.0 * (2.0/3.0 - tr));
01522     else                   r = t1;
01523     r *= RGB_R_UPPER; p[0] = clamped_convert<T>(r);
01524 
01525     // set GREEN
01526     const double tg = hk;
01527     if      (tg < 0) tg = tr + 1;
01528     else if (tg > 1) tg = tg - 1;
01529     if      (tg < 1.0/6.0) g = t1 + ((t2 - t1) * 6.0 * tg);
01530     else if (tg < 1.0/2.0) g = t2;
01531     else if (tg < 2.0/3.0) g = t1 + ((t2 - t1) * 6.0 * (2.0/3.0 - tg));
01532     else                   g = t1;
01533     g *= RGB_G_UPPER; p[1] = clamped_convert<T>(g);
01534 
01535     // set BLUE
01536     const double tb = hk - 1.0/3.0;
01537     if      (tb < 0) tb = tb + 1;
01538     else if (tb > 1) tb = tb - 1;
01539     if      (tb < 1.0/6.0) b = t1 + ((t2 - t1) * 6.0 * tb);
01540     else if (tb < 1.0/2.0) b = t2;
01541     else if (tb < 2.0/3.0) b = t1 + ((t2 - t1) * 6.0 * (2.0/3.0 - tb));
01542     else                   b = t1;
01543     b *= RGB_B_UPPER; p[2] = clamped_convert<T>(b);
01544   }
01545 
01546 
01547 }
01548 
01549 // ######################################################################
01550 template <class T>
01551 template <class T2> inline PixRGB<T>::PixRGB(const PixH2SV1<T2>& A1)
01552   : Pixels<T,3>()
01553 {
01554   const PixH2SV1<double> A( A1 );
01555 
01556   // p[0] = r  : p[1] = g  : p[2] = b
01557   // A[0] = h1 : A[1] = h2 : A[2] = s : A[3] = v
01558 
01559   double h = 0;
01560 
01561 // SEE PixelsCommonDef.H
01562 PIX_H2SV1_TO_HSV_SIMPLE_COMMON(A[0],A[1],h)
01563 // SEE PixelsCommonDef.H
01564 PIX_HSV_TO_RGB_COMMON(h,A[2],A[3],p[0],p[1],p[2])
01565 }
01566 
01567 // ######################################################################
01568 template <class T>
01569 template <class T2> inline PixRGB<T>::PixRGB(const PixH2SV2<T2>& A1)
01570   : Pixels<T,3>()
01571 {
01572 
01573   const PixH2SV2<double> A( A1 );
01574 
01575   // p[0] = r  : p[1] = g  : p[2] = b
01576   // A[0] = h1 : A[1] = h2 : A[2] = s : A[3] = v
01577 
01578   double h  = 0;
01579   double sf = 0;
01580 
01581 // SEE PixelsCommonDef.H
01582 PIX_H2SV2_TO_HSV_ROBUST_COMMON(A[0],A[1],A[2],h,sf)
01583 // SEE PixelsCommonDef.H
01584 PIX_HSV_TO_RGB_COMMON(h,sf,A[3],p[0],p[1],p[2])
01585 }
01586 
01587 // ######################################################################
01588 template <class T>
01589 template <class T2> inline PixRGB<T>::PixRGB(const PixHyper<T2,3>& A)
01590   : Pixels<T,3>()
01591 {
01592   pix_helper::clamped_assign_3(*this, A);
01593 }
01594 
01595 // ######################################################################
01596 // Standard Constructors / Destrcutor
01597 // ######################################################################
01598 
01599 template <class T>
01600 inline PixRGB<T>::PixRGB() : Pixels<T,3>()
01601 {}
01602 
01603 // ######################################################################
01604 template <class T>
01605 inline PixRGB<T>::~PixRGB()
01606 {}
01607 
01608 // ######################################################################
01609 template <class T>
01610 inline PixRGB<T>::PixRGB(const T val) : Pixels<T,3>(val)
01611 {}
01612 
01613 // ######################################################################
01614 template <class T>
01615 template <class T2>
01616 inline PixRGB<T>::PixRGB(const T2 val)
01617   :
01618   Pixels<T,3>(clamped_convert<T>(val))
01619 {}
01620 
01621 // ######################################################################
01622 // Special methods for this class
01623 // ######################################################################
01624 
01625 template <class T>
01626 inline void PixRGB<T>::getRGB(T& r, T& g, T& b) const
01627 {
01628   r = p[0]; g = p[1]; b = p[2];
01629 }
01630 
01631 template <class T>
01632 inline PixRGB<T>::PixRGB(const PixRGB<T>& pix) : Pixels<T,3>(pix)
01633 {}
01634 
01635 // ######################################################################
01636 template <class T>
01637 inline PixRGB<T>::PixRGB(const T redval, const T greenval, const T blueval) : Pixels<T,3>()
01638 {
01639   p[0] = redval; p[1] = greenval; p[2] = blueval;
01640 }
01641 
01642 // ######################################################################
01643 template <class T> template <class T2, class T3, class T4> inline
01644 PixRGB<T>::PixRGB(const T2 redval, const T3 greenval, const T4 blueval) : Pixels<T,3>()
01645 {
01646   p[0] = clamped_convert<T>(redval);
01647   p[1] = clamped_convert<T>(greenval);
01648   p[2] = clamped_convert<T>(blueval);
01649 }
01650 
01651 // ######################################################################
01652 template <class T> inline T PixRGB<T>::red() const
01653 {
01654   return p[0];
01655 }
01656 
01657 // ######################################################################
01658 template <class T> inline T PixRGB<T>::green() const
01659 {
01660   return p[1];
01661 }
01662 
01663 // ######################################################################
01664 template <class T> inline T PixRGB<T>::blue() const
01665 {
01666   return p[2];
01667 }
01668 
01669 // ######################################################################
01670 template <class T>
01671 template <class T2> inline void PixRGB<T>::setRed(const T2 redval)
01672 {
01673   p[0] = clamped_convert<T>(redval);
01674 }
01675 
01676 // ######################################################################
01677 template <class T>
01678 template <class T2> inline void PixRGB<T>::setGreen(const T2 greenval)
01679 {
01680   p[1] = clamped_convert<T>(greenval);
01681 }
01682 
01683 // ######################################################################
01684 template <class T>
01685 template <class T2> inline void PixRGB<T>::setBlue(const T2 blueval)
01686 {
01687   p[2] = clamped_convert<T>(blueval);
01688 }
01689 
01690 // ######################################################################
01691 template <class T> template <class T2, class T3, class T4> inline void
01692 PixRGB<T>::set(const T2 redval, const T3 greenval, const T4 blueval)
01693 {
01694   p[0] = clamped_convert<T>(redval);
01695   p[1] = clamped_convert<T>(greenval);
01696   p[2] = clamped_convert<T>(blueval);
01697 }
01698 
01699 // ######################################################################
01700 template <class T> inline T PixRGB<T>::luminance() const
01701 {
01702   return clamped_convert<T>( (double(p[0]) + double(p[1]) + double(p[2]))
01703                              / 3.0 );
01704 }
01705 
01706 // ######################################################################
01707 template <class T>
01708 inline void PixRGB<T>::getHSV(T& h1, T& h2, T& s, T& v) const
01709 {
01710   const PixH2SV1<double> temph2sv1(*this);
01711   h1 = temph2sv1.p[0];
01712   h2 = temph2sv1.p[1];
01713   s  = temph2sv1.p[2];
01714   v  = temph2sv1.p[3];
01715 }
01716 
01717 // ######################################################################
01718 template <class T>
01719 inline void PixRGB<T>::setHSV(const T h1, const T h2, const T s, const T v)
01720 {
01721   T H1 = h1; T H2 = h2; T S = s; T V = v;
01722   PixH2SV1<T> A(H1,H2,S,V);
01723   *this = A;
01724 }
01725 
01726 // ######################################################################
01727 // ######################################################################
01728 // Pixels HSV
01729 // ######################################################################
01730 // ######################################################################
01731 
01732 // ######################################################################
01733 // constructors for where Pix<T> != Pix<T2> - with conversion
01734 // ######################################################################
01735 
01736 template <class T>
01737 template <class T2> inline PixHSV<T>::PixHSV(const PixRGB<T2>& A1)
01738   : Pixels<T,3>()
01739 {
01740   const PixRGB<double> A( A1 );
01741 
01742   // p[0] = h : p[1] = s : p[2] = v
01743   // A[0] = r : A[1] = g : A[2] = b
01744 
01745 PIX_RGB_TO_HSV_COMMON(A[0],A[1],A[2],p[0],p[1],p[2],true)
01746 
01747 }
01748 
01749 // ######################################################################
01750 template <class T>
01751 template <class T2> inline PixHSV<T>::PixHSV(const PixHSV<T2>& A)
01752   : Pixels<T,3>()
01753 {
01754   pix_helper::clamped_assign_3(*this, A);
01755 }
01756 
01757 // ######################################################################
01758 template <class T>
01759 template <class T2> inline PixHSV<T>::PixHSV(const PixYIQ<T2>& A1)
01760   : Pixels<T,3>()
01761 {
01762   const PixYIQ<double> A( A1 );
01763   const PixRGB<double> B( A );
01764   const PixHSV<double> C( B );
01765   pix_helper::clamped_assign_3(*this, C);
01766 }
01767 
01768 // ######################################################################
01769 template <class T>
01770 template <class T2> inline PixHSV<T>::PixHSV(const PixHSL<T2>& A1)
01771   : Pixels<T,3>()
01772 {
01773   const PixHSL<double> A( A1 );
01774   const PixRGB<double> B( A );
01775   const PixHSV<double> C( B );
01776   pix_helper::clamped_assign_3(*this, C);
01777 }
01778 
01779 // ######################################################################
01780 template <class T>
01781 template <class T2> inline PixHSV<T>::PixHSV(const PixH2SV1<T2>& A1)
01782   : Pixels<T,3>()
01783 {
01784   const PixH2SV1<double> A( A1 );
01785   // A[0] = H1, A[1] = H2
01786 
01787 // SEE PixelsCommonDef.H
01788 PIX_H2SV1_TO_HSV_SIMPLE_COMMON(A[0],A[1],p[0])
01789 
01790   p[1] = clamped_convert<T>(A[2]*HSV_S_UPPER);
01791   p[2] = clamped_convert<T>(A[3]*HSV_V_UPPER);
01792 }
01793 
01794 // ######################################################################
01795 template <class T>
01796 template <class T2> inline PixHSV<T>::PixHSV(const PixH2SV2<T2>& A1)
01797   : Pixels<T,3>()
01798 {
01799   const PixH2SV2<double> A( A1 );
01800 
01801   double h  = 0;
01802   double sf = 0;
01803 
01804 // SEE PixelsCommonDef.H
01805 PIX_H2SV2_TO_HSV_ROBUST_COMMON(A[0],A[1],A[2],p[0],sf)
01806 
01807   p[1] = clamped_convert<T>(sf*HSV_S_UPPER);
01808   p[2] = clamped_convert<T>(A[3]*HSV_V_UPPER);
01809 }
01810 
01811 // ######################################################################
01812 template <class T>
01813 template <class T2> inline PixHSV<T>::PixHSV(const PixHyper<T2,3>& A)
01814   : Pixels<T,3>()
01815 {
01816   pix_helper::clamped_assign_3(*this, A);
01817 }
01818 
01819 // ######################################################################
01820 // Standard Constructors / Destrcutor
01821 // ######################################################################
01822 
01823 template <class T>
01824 inline PixHSV<T>::PixHSV() : Pixels<T,3>()
01825 {}
01826 
01827 // ######################################################################
01828 template <class T>
01829 inline PixHSV<T>::~PixHSV()
01830 {}
01831 
01832 // ######################################################################
01833 template <class T>
01834 inline PixHSV<T>::PixHSV(const T val) : Pixels<T,3>(val)
01835 {}
01836 
01837 // ######################################################################
01838 template <class T>
01839 inline PixHSV<T>::PixHSV(const PixHSV<T>& pix) : Pixels<T,3>(pix)
01840 {}
01841 
01842 // ######################################################################
01843 // Special methods for this class
01844 // ######################################################################
01845 
01846 template <class T>
01847 inline void PixHSV<T>::getHSV(T& h, T& s, T& v) const
01848 {
01849   h = p[0]; s = p[1]; v = p[2];
01850 }
01851 
01852 // ######################################################################
01853 template <class T>
01854 inline PixHSV<T>::PixHSV(const T Hval, const T Sval, const T Vval) : Pixels<T,3>()
01855 {
01856   p[0] = Hval; p[1] = Sval; p[2] = Vval;
01857 }
01858 
01859 // ######################################################################
01860 template <class T> template <class T2, class T3, class T4> inline
01861 PixHSV<T>::PixHSV(const T2 Hval, const T3 Sval, const T4 Vval) : Pixels<T,3>()
01862 {
01863   p[0] = clamped_convert<T>(Hval);
01864   p[1] = clamped_convert<T>(Sval);
01865   p[2] = clamped_convert<T>(Vval);
01866 }
01867 
01868 // ######################################################################
01869 template <class T>
01870 inline T PixHSV<T>::H() const
01871 {
01872   return p[0];
01873 }
01874 
01875 // ######################################################################
01876 template <class T>
01877 inline T PixHSV<T>::S() const
01878 {
01879   return p[1];
01880 }
01881 
01882 // ######################################################################
01883 template <class T>
01884 inline T PixHSV<T>::V() const
01885 {
01886   return p[2];
01887 }
01888 
01889 // ######################################################################
01890 template <class T>
01891 template <class T2> inline void PixHSV<T>::setH(const T2 hh)
01892 {
01893   p[0] = clamped_convert<T>(hh);
01894 }
01895 
01896 // ######################################################################
01897 template <class T>
01898 template <class T2> inline void PixHSV<T>::setS(const T2 ss)
01899 {
01900   p[1] = clamped_convert<T>(ss);
01901 }
01902 
01903 // ######################################################################
01904 template <class T>
01905 template <class T2> inline void PixHSV<T>::setV(const T2 vv)
01906 {
01907   p[2] = clamped_convert<T>(vv);
01908 }
01909 
01910 // ######################################################################
01911 // ######################################################################
01912 // Pixels YUV
01913 // ######################################################################
01914 // ######################################################################
01915 
01916 // ######################################################################
01917 // constructors for where Pix<T> != Pix<T2> - with conversion
01918 // ######################################################################
01919 
01920 // ######################################################################
01921 template <class T>
01922 template <class T2> inline PixJpegYUV<T>::PixJpegYUV(const PixJpegYUV<T2>& A)
01923   : Pixels<T,3>()
01924 {
01925   pix_helper::clamped_assign_3(*this, A);
01926 }
01927 
01928 template <class T>
01929 template <class T2> inline PixJpegYUV<T>::PixJpegYUV(const PixRGB<T2>& A)
01930   : Pixels<T,3>()
01931 {
01932   // p[0] = y : p[1] = u : p[2] = v
01933   // A[0] = r : A[1] = g : A[2] = b
01934   const double yf =
01935     JPEGYUV_Y_R*A[0] + JPEGYUV_Y_G*A[1] + JPEGYUV_Y_B*A[2];
01936   const double uf =
01937     JPEGYUV_U_R*A[0] + JPEGYUV_U_G*A[1] + JPEGYUV_U_B*A[2]
01938     + JPEGYUV_UV_OFFSET;
01939   const double vf =
01940     JPEGYUV_V_R*A[0] + JPEGYUV_V_G*A[1] + JPEGYUV_V_B*A[2]
01941     + JPEGYUV_UV_OFFSET;
01942 
01943   p[0] = clamped_rounded_convert<T>(clampValue(yf, 0.0, 255.0));
01944   p[1] = clamped_rounded_convert<T>(clampValue(uf, 0.0, 255.0));
01945   p[2] = clamped_rounded_convert<T>(clampValue(vf, 0.0, 255.0));
01946 }
01947 
01948 // ######################################################################
01949 template <class T>
01950 template <class T2> inline PixJpegYUV<T>::PixJpegYUV(const PixHyper<T2,3>& A)
01951   : Pixels<T,3>()
01952 {
01953   pix_helper::clamped_assign_3(*this, A);
01954 }
01955 
01956 // ######################################################################
01957 // Standard Constructors / Destrcutor
01958 // ######################################################################
01959 
01960 template <class T>
01961 inline PixJpegYUV<T>::PixJpegYUV() : Pixels<T,3>()
01962 {}
01963 
01964 // ######################################################################
01965 template <class T>
01966 inline PixJpegYUV<T>::~PixJpegYUV()
01967 {}
01968 
01969 // ######################################################################
01970 template <class T>
01971 inline PixJpegYUV<T>::PixJpegYUV(const T val) : Pixels<T,3>(val)
01972 {}
01973 
01974 // ######################################################################
01975 template <class T>
01976 inline PixJpegYUV<T>::PixJpegYUV(const PixJpegYUV<T>& pix)
01977   : Pixels<T,3>(pix)
01978 {}
01979 
01980 
01981 // ######################################################################
01982 // Special methods for this class
01983 // ######################################################################
01984 
01985 template <class T>
01986 inline PixJpegYUV<T>::PixJpegYUV(const T Yval, const T Uval, const T Vval)
01987   : Pixels<T,3>()
01988 {
01989   p[0] = Yval; p[1] = Uval; p[2] = Vval;
01990 }
01991 
01992 // ######################################################################
01993 template <class T> template <class T2, class T3, class T4> inline
01994 PixJpegYUV<T>::PixJpegYUV(const T2 Yval, const T3 Uval, const T4 Vval) : Pixels<T,3>()
01995 {
01996   p[0] = clamped_convert<T>(Yval);
01997   p[1] = clamped_convert<T>(Uval);
01998   p[2] = clamped_convert<T>(Vval);
01999 }
02000 
02001 // ######################################################################
02002 template <class T>
02003 inline T PixJpegYUV<T>::Y() const
02004 {
02005   return p[0];
02006 }
02007 
02008 // ######################################################################
02009 template <class T>
02010 inline T PixJpegYUV<T>::U() const
02011 {
02012   return p[1];
02013 }
02014 
02015 // ######################################################################
02016 template <class T>
02017 inline T PixJpegYUV<T>::V() const
02018 {
02019   return p[2];
02020 }
02021 
02022 // ######################################################################
02023 template <class T>
02024 template <class T2> inline void PixJpegYUV<T>::setY(const T2 yy)
02025 {
02026   p[0] = clamped_convert<T>(yy);
02027 }
02028 
02029 // ######################################################################
02030 template <class T>
02031 template <class T2> inline void PixJpegYUV<T>::setU(const T2 uu)
02032 {
02033   p[1] = clamped_convert<T>(uu);
02034 }
02035 
02036 // ######################################################################
02037 template <class T>
02038 template <class T2> inline void PixJpegYUV<T>::setV(const T2 vv)
02039 {
02040   p[2] = clamped_convert<T>(vv);
02041 }
02042 
02043 // ######################################################################
02044 // ######################################################################
02045 // Pixels YUV
02046 // ######################################################################
02047 // ######################################################################
02048 
02049 // ######################################################################
02050 // constructors for where Pix<T> != Pix<T2> - with conversion
02051 // ######################################################################
02052 
02053 // ######################################################################
02054 template <class T>
02055 template <class T2> inline PixVideoYUV<T>::PixVideoYUV(const PixVideoYUV<T2>& A)
02056   : Pixels<T,3>()
02057 {
02058   pix_helper::clamped_assign_3(*this, A);
02059 }
02060 
02061 template <class T>
02062 template <class T2> inline PixVideoYUV<T>::PixVideoYUV(const PixRGB<T2>& A)
02063   : Pixels<T,3>()
02064 {
02065   // p[0] = y : p[1] = u : p[2] = v
02066   // A[0] = r : A[1] = g : A[2] = b
02067 
02068   const double yf =
02069     VIDEOYUV_Y_R*A[0] + VIDEOYUV_Y_G*A[1] + VIDEOYUV_Y_B*A[2]
02070     + double(VIDEOYUV_Y_OFFSET);
02071   const double uf =
02072     VIDEOYUV_U_R*A[0] + VIDEOYUV_U_G*A[1] + VIDEOYUV_U_B*A[2]
02073     + double(VIDEOYUV_UV_OFFSET);
02074   const double vf =
02075     VIDEOYUV_V_R*A[0] + VIDEOYUV_V_G*A[1] + VIDEOYUV_V_B*A[2]
02076     + double(VIDEOYUV_UV_OFFSET);
02077 
02078   p[0] = clamped_rounded_convert<T>(clampValue(yf, 0.0, 255.0));
02079   p[1] = clamped_rounded_convert<T>(clampValue(uf, 0.0, 255.0));
02080   p[2] = clamped_rounded_convert<T>(clampValue(vf, 0.0, 255.0));
02081 }
02082 
02083 // ######################################################################
02084 template <class T>
02085 template <class T2> inline PixVideoYUV<T>::PixVideoYUV(const PixHyper<T2,3>& A)
02086   : Pixels<T,3>()
02087 {
02088   pix_helper::clamped_assign_3(*this, A);
02089 }
02090 
02091 // ######################################################################
02092 // Standard Constructors / Destrcutor
02093 // ######################################################################
02094 
02095 template <class T>
02096 inline PixVideoYUV<T>::PixVideoYUV() : Pixels<T,3>()
02097 {}
02098 
02099 // ######################################################################
02100 template <class T>
02101 inline PixVideoYUV<T>::~PixVideoYUV()
02102 {}
02103 
02104 // ######################################################################
02105 template <class T>
02106 inline PixVideoYUV<T>::PixVideoYUV(const T val) : Pixels<T,3>(val)
02107 {}
02108 
02109 // ######################################################################
02110 template <class T>
02111 inline PixVideoYUV<T>::PixVideoYUV(const PixVideoYUV<T>& pix)
02112   : Pixels<T,3>(pix)
02113 {}
02114 
02115 
02116 // ######################################################################
02117 // Special methods for this class
02118 // ######################################################################
02119 
02120 template <class T>
02121 inline void PixVideoYUV<T>::getVideoYUV(T& y, T& u, T& v) const
02122 {
02123   y = p[0]; u = p[1]; v = p[2];
02124 }
02125 
02126 template <class T>
02127 inline PixVideoYUV<T>::PixVideoYUV(const T Yval, const T Uval, const T Vval)
02128   : Pixels<T,3>()
02129 {
02130   p[0] = Yval; p[1] = Uval; p[2] = Vval;
02131 }
02132 
02133 // ######################################################################
02134 template <class T> template <class T2, class T3, class T4> inline
02135 PixVideoYUV<T>::PixVideoYUV(const T2 Yval, const T3 Uval, const T4 Vval) : Pixels<T,3>()
02136 {
02137   p[0] = clamped_convert<T>(Yval);
02138   p[1] = clamped_convert<T>(Uval);
02139   p[2] = clamped_convert<T>(Vval);
02140 }
02141 
02142 // ######################################################################
02143 template <class T>
02144 inline T PixVideoYUV<T>::Y() const
02145 {
02146   return p[0];
02147 }
02148 
02149 // ######################################################################
02150 template <class T>
02151 inline T PixVideoYUV<T>::U() const
02152 {
02153   return p[1];
02154 }
02155 
02156 // ######################################################################
02157 template <class T>
02158 inline T PixVideoYUV<T>::V() const
02159 {
02160   return p[2];
02161 }
02162 
02163 // ######################################################################
02164 template <class T>
02165 template <class T2> inline void PixVideoYUV<T>::setY(const T2 yy)
02166 {
02167   p[0] = clamped_convert<T>(yy);
02168 }
02169 
02170 // ######################################################################
02171 template <class T>
02172 template <class T2> inline void PixVideoYUV<T>::setU(const T2 uu)
02173 {
02174   p[1] = clamped_convert<T>(uu);
02175 }
02176 
02177 // ######################################################################
02178 template <class T>
02179 template <class T2> inline void PixVideoYUV<T>::setV(const T2 vv)
02180 {
02181   p[2] = clamped_convert<T>(vv);
02182 }
02183 
02184 // ######################################################################
02185 // ######################################################################
02186 // Pixels YIQ
02187 // ######################################################################
02188 // ######################################################################
02189 
02190 // ######################################################################
02191 // constructors for where Pix<T> != Pix<T2> - with conversion
02192 // ######################################################################
02193 
02194 template <class T>
02195 template <class T2> inline PixYIQ<T>::PixYIQ(const PixRGB<T2>& A1)
02196   : Pixels<T,3>()
02197 {
02198   const PixRGB<double> A( A1 );
02199   // coeffs from Foley & Van Dam
02200   // p[0] = y   : p[1] = i   : p[2] = q
02201   // A[0] = r : A[1] = g : A[2] = b
02202   p[0] = clamped_rounded_convert<T>(0.299 * A[0] + 0.587 * A[1] + 0.114 * A[2]);
02203   p[1] = clamped_rounded_convert<T>(0.596 * A[0] - 0.275 * A[1] - 0.321 * A[2]);
02204   p[2] = clamped_rounded_convert<T>(0.212 * A[0] - 0.523 * A[1] + 0.311 * A[2]);
02205 }
02206 
02207 // ######################################################################
02208 template <class T>
02209 template <class T2> inline PixYIQ<T>::PixYIQ(const PixHSV<T2>& A1)
02210   : Pixels<T,3>()
02211 {
02212   const PixHSV<double> A( A1 );
02213   const PixRGB<double> B( A );
02214   const PixYIQ<double> C( B );
02215   pix_helper::clamped_assign_3(*this, C);
02216 }
02217 
02218 // ######################################################################
02219 template <class T>
02220 template <class T2> inline PixYIQ<T>::PixYIQ(const PixYIQ<T2>& A)
02221   : Pixels<T,3>()
02222 {
02223   pix_helper::clamped_assign_3(*this, A);
02224 }
02225 
02226 // ######################################################################
02227 template <class T>
02228 template <class T2> inline PixYIQ<T>::PixYIQ(const PixHSL<T2>& A1)
02229   : Pixels<T,3>()
02230 {
02231   const PixHSL<double> A( A1 );
02232   const PixRGB<double> B( A );
02233   const PixYIQ<double> C( B );
02234   pix_helper::clamped_assign_3(*this, C);
02235 }
02236 
02237 // ######################################################################
02238 template <class T>
02239 template <class T2> inline PixYIQ<T>::PixYIQ(const PixH2SV1<T2>& A1)
02240   : Pixels<T,3>()
02241 {
02242   const PixH2SV1<double> A( A1 );
02243   const PixRGB<double> B( A );
02244   const PixYIQ<double> C( B );
02245   pix_helper::clamped_assign_3(*this, C);
02246 }
02247 
02248 // ######################################################################
02249 template <class T>
02250 template <class T2> inline PixYIQ<T>::PixYIQ(const PixH2SV2<T2>& A1)
02251   : Pixels<T,3>()
02252 {
02253   const PixH2SV2<double> A( A1 );
02254   const PixRGB<double> B( A );
02255   const PixYIQ<double> C( B );
02256   pix_helper::clamped_assign_3(*this, C);
02257 }
02258 
02259 // ######################################################################
02260 template <class T>
02261 template <class T2> inline PixYIQ<T>::PixYIQ(const PixH2SV3<T2>& A1)
02262   : Pixels<T,3>()
02263 {
02264   const PixH2SV3<double> A( A1 );
02265   const PixRGB<double> B( A );
02266   const PixYIQ<double> C( B );
02267   pix_helper::clamped_assign_3(*this, C);
02268 }
02269 
02270 // ######################################################################
02271 template <class T>
02272 template <class T2> inline PixYIQ<T>::PixYIQ(const PixHyper<T2,3>& A)
02273   : Pixels<T,3>()
02274 {
02275   pix_helper::clamped_assign_3(*this, A);
02276 }
02277 
02278 // ######################################################################
02279 // Standard Constructors / Destructor
02280 // ######################################################################
02281 
02282 template <class T>
02283 inline PixYIQ<T>::PixYIQ() : Pixels<T,3>()
02284 {}
02285 
02286 // ######################################################################
02287 template <class T>
02288 inline PixYIQ<T>::~PixYIQ()
02289 {}
02290 
02291 // ######################################################################
02292 template <class T>
02293 inline PixYIQ<T>::PixYIQ(const T val) : Pixels<T,3>(val)
02294 {}
02295 
02296 // ######################################################################
02297 template <class T>
02298 inline PixYIQ<T>::PixYIQ(const PixYIQ<T>& pix) : Pixels<T,3>(pix)
02299 {}
02300 
02301 // ######################################################################
02302 // Special methods for this class
02303 // ######################################################################
02304 
02305 template <class T>
02306 inline void PixYIQ<T>::getYIQ(T& y, T& i, T& q) const
02307 {
02308   y = p[0]; i = p[1]; q = p[2];
02309 }
02310 
02311 // ######################################################################
02312 template <class T>
02313 inline PixYIQ<T>::PixYIQ(const T Yval, const T Ival, const T Qval) : Pixels<T,3>()
02314 {
02315     p[0] = Yval; p[1] = Ival; p[2] = Qval;
02316 }
02317 
02318 // ######################################################################
02319 template <class T> template <class T2, class T3, class T4> inline
02320 PixYIQ<T>::PixYIQ(const T2 Yval, const T3 Ival, const T4 Qval) : Pixels<T,3>()
02321 {
02322   p[0] = clamped_convert<T>(Yval);
02323   p[1] = clamped_convert<T>(Ival);
02324   p[2] = clamped_convert<T>(Qval);
02325 }
02326 
02327 // ######################################################################
02328 template <class T>
02329 inline T PixYIQ<T>::Y() const
02330 {
02331   return p[0];
02332 }
02333 
02334 // ######################################################################
02335 template <class T>
02336 inline T PixYIQ<T>::I() const
02337 {
02338   return p[1];
02339 }
02340 
02341 // ######################################################################
02342 template <class T>
02343 inline T PixYIQ<T>::Q() const
02344 {
02345   return p[2];
02346 }
02347 
02348 // ######################################################################
02349 template <class T>
02350 template <class T2> inline void PixYIQ<T>::setY(const T2 yy)
02351 {
02352   p[0] = clamped_convert<T>(yy);
02353 }
02354 
02355 // ######################################################################
02356 template <class T>
02357 template <class T2> inline void PixYIQ<T>::setI(const T2 ii)
02358 {
02359   p[1] = clamped_convert<T>(ii);
02360 }
02361 
02362 // ######################################################################
02363 template <class T>
02364 template <class T2> inline void PixYIQ<T>::setQ(const T2 qq)
02365 {
02366   p[2] = clamped_convert<T>(qq);
02367 }
02368 
02369 
02370 // ######################################################################
02371 // ######################################################################
02372 // Pixels HSL
02373 // ######################################################################
02374 // ######################################################################
02375 
02376 // ######################################################################
02377 // constructors for where Pix<T> != Pix<T2> - with conversion
02378 // ######################################################################
02379 
02380 template <class T>
02381 template <class T2> inline PixHSL<T>::PixHSL(const PixRGB<T2>& A1)
02382   : Pixels<T,3>()
02383 {
02384   const PixRGB<double> A( A1 );
02385 
02386   // p[0] = h : p[1] = s : p[2] = l
02387   // A[0] = r : A[1] = g : A[2] = b
02388 
02389   const double R = A[0]/RGB_R_UPPER;
02390   const double G = A[1]/RGB_G_UPPER;
02391   const double B = A[2]/RGB_B_UPPER;
02392 
02393   double h,s,l;
02394 
02395   //Note: HSL is very much like HSV. For instance hue is computed in
02396   //      exactly the same way.
02397 
02398   if((B > G) && (B > R))
02399   {
02400     const double max = B;
02401     double min;
02402     if(R > G) min = G;
02403     else      min = R;
02404     const double posDelta = max + min;
02405     const double negDelta = max - min;
02406     l = posDelta/2;
02407     if(l > 0.5)       s = negDelta/(2 - posDelta);
02408     else              s = negDelta/posDelta;
02409     if(negDelta != 0) h = 4 + (R - G) / negDelta;
02410     else              h = 4 + (R - G);
02411     h *= 60; if(h < 0) h += 360;
02412   }
02413   else if(G > R)
02414   {
02415     const double max = G;
02416     double min;
02417     if(R > B) min = B;
02418     else      min = R;
02419     const double posDelta = max + min;
02420     const double negDelta = max - min;
02421     l = posDelta/2;
02422     if(l > 0.5)       s = negDelta/(2 - posDelta);
02423     else              s = negDelta/posDelta;
02424     if(negDelta != 0) h = 2 + (B - R) / negDelta;
02425     else              h = 2 + (B - R);
02426     h *= 60; if(h < 0) h += 360;
02427   }
02428   else
02429   {
02430     const double max = R;
02431     double min;
02432     if(G > B) min = B;
02433     else      min = G;
02434     const double posDelta = max + min;
02435     const double negDelta = max - min;
02436     l = posDelta/2;
02437     if(l > 0.5)       s = negDelta/(2 - posDelta);
02438     else              s = negDelta/posDelta;
02439     if(negDelta != 0) h = (G - B) / negDelta;
02440     else              h = (G - B);
02441     h *= 60; if(h < 0) h += 360;
02442   }
02443 
02444   p[0] = clamped_convert<T>(h);
02445   p[1] = clamped_convert<T>(s);
02446   p[2] = clamped_convert<T>(l);
02447 }
02448 
02449 // ######################################################################
02450 template <class T>
02451 template <class T2> inline PixHSL<T>::PixHSL(const PixHSV<T2>& A1)
02452   : Pixels<T,3>()
02453 {
02454   const PixHSV<double> A( A1 );
02455   const PixRGB<double> B( A );
02456   const PixHSL<double> C( B );
02457   pix_helper::clamped_assign_3(*this, C);
02458 }
02459 
02460 // ######################################################################
02461 template <class T>
02462 template <class T2> inline PixHSL<T>::PixHSL(const PixYIQ<T2>& A1)
02463   : Pixels<T,3>()
02464 {
02465   const PixYIQ<double> A( A1 );
02466   const PixRGB<double> B( A );
02467   const PixHSL<double> C( B );
02468   pix_helper::clamped_assign_3(*this, C);
02469 }
02470 
02471 // ######################################################################
02472 template <class T>
02473 template <class T2> inline PixHSL<T>::PixHSL(const PixHSL<T2>& A)
02474   : Pixels<T,3>()
02475 {
02476   pix_helper::clamped_assign_3(*this, A);
02477 }
02478 
02479 // ######################################################################
02480 template <class T>
02481 template <class T2> inline PixHSL<T>::PixHSL(const PixH2SV1<T2>& A1)
02482   : Pixels<T,3>()
02483 {
02484   const PixH2SV1<double> A( A1 );
02485   // A[0] = H1, A[1] = H2
02486 
02487 PIX_H2SV1_TO_HSV_SIMPLE_COMMON(A[0],A[1],p[0])
02488 
02489   p[1] = clamped_convert<T>(A[2]*HSL_S_UPPER);
02490   p[2] = clamped_convert<T>(A[3]*HSL_L_UPPER);
02491 }
02492 
02493 // ######################################################################
02494 template <class T>
02495 template <class T2> inline PixHSL<T>::PixHSL(const PixH2SV2<T2>& A1)
02496   : Pixels<T,3>()
02497 {
02498   const PixH2SV2<double> A( A1 );
02499 
02500   double h  = 0;
02501   double sf = 0;
02502 
02503 // SEE PixelsCommonDef.H
02504 PIX_H2SV2_TO_HSV_ROBUST_COMMON(A[0],A[1],A[2],p[0],sf)
02505 
02506   p[1] = clamped_convert<T>(sf*HSL_S_UPPER);
02507   p[2] = clamped_convert<T>(A[3]*HSL_L_UPPER);
02508 }
02509 
02510 // ######################################################################
02511 template <class T>
02512 template <class T2> inline PixHSL<T>::PixHSL(const PixHyper<T2,3>& A)
02513   : Pixels<T,3>()
02514 {
02515   pix_helper::clamped_assign_3(*this, A);
02516 }
02517 
02518 // ######################################################################
02519 // Standard Constructors / Destrcutor
02520 // ######################################################################
02521 
02522 template <class T>
02523 inline PixHSL<T>::PixHSL() : Pixels<T,3>()
02524 {}
02525 
02526 // ######################################################################
02527 template <class T>
02528 inline PixHSL<T>::~PixHSL()
02529 {}
02530 
02531 // ######################################################################
02532 template <class T>
02533 inline PixHSL<T>::PixHSL(const T val) : Pixels<T,3>(val)
02534 {}
02535 
02536 // ######################################################################
02537 template <class T>
02538 inline PixHSL<T>::PixHSL(const PixHSL<T>& pix) : Pixels<T,3>(pix)
02539 {}
02540 
02541 // ######################################################################
02542 // Special methods for this class
02543 // ######################################################################
02544 
02545 template <class T>
02546 inline void PixHSL<T>::getHSL(T& h, T& s, T& l) const
02547 {
02548   h = p[0]; s = p[1]; l = p[2];
02549 }
02550 
02551 // ######################################################################
02552 template <class T>
02553 inline PixHSL<T>::PixHSL(const T Hval, const T Sval, const T Lval) : Pixels<T,3>()
02554 {
02555   p[0] = Hval; p[1] = Sval; p[2] = Lval;
02556 }
02557 
02558 // ######################################################################
02559 template <class T> template <class T2, class T3, class T4> inline
02560 PixHSL<T>::PixHSL(const T2 Hval, const T3 Sval, const T4 Lval) : Pixels<T,3>()
02561 {
02562   p[0] = clamped_convert<T>(Hval);
02563   p[1] = clamped_convert<T>(Sval);
02564   p[2] = clamped_convert<T>(Lval);
02565 }
02566 
02567 // ######################################################################
02568 template <class T>
02569 inline T PixHSL<T>::H() const
02570 {
02571   return p[0];
02572 }
02573 
02574 // ######################################################################
02575 template <class T>
02576 inline T PixHSL<T>::S() const
02577 {
02578   return p[1];
02579 }
02580 
02581 // ######################################################################
02582 template <class T>
02583 inline T PixHSL<T>::L() const
02584 {
02585   return p[2];
02586 }
02587 
02588 // ######################################################################
02589 template <class T>
02590 template <class T2> inline void PixHSL<T>::setH(const T2 hh)
02591 {
02592   p[0] = clamped_convert<T>(hh);
02593 }
02594 
02595 // ######################################################################
02596 template <class T>
02597 template <class T2> inline void PixHSL<T>::setS(const T2 ss)
02598 {
02599   p[1] = clamped_convert<T>(ss);
02600 }
02601 
02602 // ######################################################################
02603 template <class T>
02604 template <class T2> inline void PixHSL<T>::setL(const T2 ll)
02605 {
02606   p[2] = clamped_convert<T>(ll);
02607 }
02608 // ######################################################################
02609 // ######################################################################
02610 // Pixels Lab
02611 // ######################################################################
02612 // ######################################################################
02613 
02614 // ######################################################################
02615 // constructors for where Pix<T> != Pix<T2> - with conversion
02616 // ######################################################################
02617 
02618 template <class T>
02619 template <class T2> inline PixLab<T>::PixLab(const PixRGB<T2>& A1)
02620   : Pixels<T,3>()
02621 {
02622   const PixRGB<double> A( A1 );
02623 
02624   // p[0] = l : p[1] = a : p[2] = b
02625   // A[0] = r : A[1] = g : A[2] = b
02626 
02627   double X,Y,Z,L,a,b;
02628 
02629 // SEE PixelsCommonDef.H
02630 PIX_RGB_TO_XYZ_OPENCV_COMMON(A[0],A[1],A[2],X,Y,Z)
02631 // SEE PixelsCommonDef.H
02632 PIX_XYZ_TO_LAB_OPENCV_COMMON(X,Y,Z,L,a,b)
02633 //PIX_XYZ_TO_LAB_AUGMENT_COMMON(X,Y,Z,L,a,b)
02634 
02635   p[0] = clamped_convert<T>(L);
02636   p[1] = clamped_convert<T>(a);
02637   p[2] = clamped_convert<T>(b);
02638 }
02639 
02640 // ######################################################################
02641 template <class T>
02642 template <class T2> inline PixLab<T>::PixLab(const PixLab<T2>& A)
02643   : Pixels<T,3>()
02644 {
02645   pix_helper::clamped_assign_3(*this, A);
02646 }
02647 
02648 // ######################################################################
02649 template <class T>
02650 template <class T2> inline PixLab<T>::PixLab(const PixHyper<T2,3>& A)
02651   : Pixels<T,3>()
02652 {
02653   pix_helper::clamped_assign_3(*this, A);
02654 }
02655 
02656 // ######################################################################
02657 // Standard Constructors / Destrcutor
02658 // ######################################################################
02659 
02660 template <class T>
02661 inline PixLab<T>::PixLab() : Pixels<T,3>()
02662 {}
02663 
02664 // ######################################################################
02665 template <class T>
02666 inline PixLab<T>::~PixLab()
02667 {}
02668 
02669 // ######################################################################
02670 template <class T>
02671 inline PixLab<T>::PixLab(const T val) : Pixels<T,3>(val)
02672 {}
02673 
02674 // ######################################################################
02675 template <class T>
02676 inline PixLab<T>::PixLab(const PixLab<T>& pix) : Pixels<T,3>(pix)
02677 {}
02678 
02679 // ######################################################################
02680 // Special methods for this class
02681 // ######################################################################
02682 
02683 template <class T>
02684 inline void PixLab<T>::getLab(T& l, T& a, T& b) const
02685 {
02686   l = p[0]; a = p[1]; b = p[2];
02687 }
02688 
02689 // ######################################################################
02690 template <class T>
02691 inline PixLab<T>::PixLab(const T Lval, const T Aval, const T Bval) : Pixels<T,3>()
02692 {
02693   p[0] = Lval; p[1] = Aval; p[2] = Bval;
02694 }
02695 
02696 // ######################################################################
02697 template <class T> template <class T2, class T3, class T4> inline
02698 PixLab<T>::PixLab(const T2 Lval, const T3 Aval, const T4 Bval) : Pixels<T,3>()
02699 {
02700   p[0] = clamped_convert<T>(Lval);
02701   p[1] = clamped_convert<T>(Aval);
02702   p[2] = clamped_convert<T>(Bval);
02703 }
02704 
02705 // ######################################################################
02706 template <class T>
02707 inline T PixLab<T>::L() const
02708 {
02709   return p[0];
02710 }
02711 
02712 // ######################################################################
02713 template <class T>
02714 inline T PixLab<T>::A() const
02715 {
02716   return p[1];
02717 }
02718 
02719 // ######################################################################
02720 template <class T>
02721 inline T PixLab<T>::B() const
02722 {
02723   return p[2];
02724 }
02725 
02726 // ######################################################################
02727 template <class T>
02728 template <class T2> inline void PixLab<T>::setL(const T2 L)
02729 {
02730   p[0] = clamped_convert<T>(L);
02731 }
02732 
02733 // ######################################################################
02734 template <class T>
02735 template <class T2> inline void PixLab<T>::setA(const T2 A)
02736 {
02737   p[1] = clamped_convert<T>(A);
02738 }
02739 
02740 // ######################################################################
02741 template <class T>
02742 template <class T2> inline void PixLab<T>::setB(const T2 B)
02743 {
02744   p[2] = clamped_convert<T>(B);
02745 }
02746 
02747 // ######################################################################
02748 // ######################################################################
02749 // Pixels XYZ
02750 // ######################################################################
02751 // ######################################################################
02752 
02753 // ######################################################################
02754 // constructors for where Pix<T> != Pix<T2> - with conversion
02755 // ######################################################################
02756 
02757 template <class T>
02758 template <class T2> inline PixXYZ<T>::PixXYZ(const PixRGB<T2>& A1)
02759   : Pixels<T,3>()
02760 {
02761   const PixRGB<double> A( A1 );
02762 
02763   // p[0] = l : p[1] = a : p[2] = b
02764   // A[0] = r : A[1] = g : A[2] = b
02765 
02766   double X,Y,Z;
02767 
02768 // SEE PixelsCommonDef.H
02769 PIX_RGB_TO_XYZ_OPENCV_COMMON(A[0],A[1],A[2],X,Y,Z)
02770 
02771   p[0] = clamped_convert<T>(X);
02772   p[1] = clamped_convert<T>(Y);
02773   p[2] = clamped_convert<T>(Z);
02774 }
02775 
02776 // ######################################################################
02777 template <class T>
02778 template <class T2> inline PixXYZ<T>::PixXYZ(const PixXYZ<T2>& A)
02779   : Pixels<T,3>()
02780 {
02781   pix_helper::clamped_assign_3(*this, A);
02782 }
02783 
02784 // ######################################################################
02785 template <class T>
02786 template <class T2> inline PixXYZ<T>::PixXYZ(const PixHyper<T2,3>& A)
02787   : Pixels<T,3>()
02788 {
02789   pix_helper::clamped_assign_3(*this, A);
02790 }
02791 
02792 // ######################################################################
02793 // Standard Constructors / Destrcutor
02794 // ######################################################################
02795 
02796 template <class T>
02797 inline PixXYZ<T>::PixXYZ() : Pixels<T,3>()
02798 {}
02799 
02800 // ######################################################################
02801 template <class T>
02802 inline PixXYZ<T>::~PixXYZ()
02803 {}
02804 
02805 // ######################################################################
02806 template <class T>
02807 inline PixXYZ<T>::PixXYZ(const T val) : Pixels<T,3>(val)
02808 {}
02809 
02810 // ######################################################################
02811 template <class T>
02812 inline PixXYZ<T>::PixXYZ(const PixXYZ<T>& pix) : Pixels<T,3>(pix)
02813 {}
02814 
02815 // ######################################################################
02816 // Special methods for this class
02817 // ######################################################################
02818 
02819 template <class T>
02820 inline void PixXYZ<T>::getXYZ(T& x, T& y, T& z) const
02821 {
02822   x = p[0]; y = p[1]; z = p[2];
02823 }
02824 
02825 // ######################################################################
02826 template <class T>
02827 inline PixXYZ<T>::PixXYZ(const T Xval, const T Yval, const T Zval) : Pixels<T,3>()
02828 {
02829   p[0] = Xval; p[1] = Yval; p[2] = Zval;
02830 }
02831 
02832 // ######################################################################
02833 template <class T> template <class T2, class T3, class T4> inline
02834 PixXYZ<T>::PixXYZ(const T2 Xval, const T3 Yval, const T4 Zval) : Pixels<T,3>()
02835 {
02836   p[0] = clamped_convert<T>(Xval);
02837   p[1] = clamped_convert<T>(Yval);
02838   p[2] = clamped_convert<T>(Zval);
02839 }
02840 
02841 // ######################################################################
02842 template <class T>
02843 inline T PixXYZ<T>::X() const
02844 {
02845   return p[0];
02846 }
02847 
02848 // ######################################################################
02849 template <class T>
02850 inline T PixXYZ<T>::Y() const
02851 {
02852   return p[1];
02853 }
02854 
02855 // ######################################################################
02856 template <class T>
02857 inline T PixXYZ<T>::Z() const
02858 {
02859   return p[2];
02860 }
02861 
02862 // ######################################################################
02863 template <class T>
02864 template <class T2> inline void PixXYZ<T>::setX(const T2 X)
02865 {
02866   p[0] = clamped_convert<T>(X);
02867 }
02868 
02869 // ######################################################################
02870 template <class T>
02871 template <class T2> inline void PixXYZ<T>::setY(const T2 Y)
02872 {
02873   p[1] = clamped_convert<T>(Y);
02874 }
02875 
02876 // ######################################################################
02877 template <class T>
02878 template <class T2> inline void PixXYZ<T>::setZ(const T2 Z)
02879 {
02880   p[2] = clamped_convert<T>(Z);
02881 }
02882 
02883 // ######################################################################
02884 // ######################################################################
02885 // Pixels H2SV1
02886 // ######################################################################
02887 // ######################################################################
02888 
02889 // ######################################################################
02890 // constructors for where Pix<T> != Pix<T2> - with conversion
02891 // ######################################################################
02892 
02893 template <class T>
02894 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixRGB<T2>& A1)
02895   : Pixels<T,4>()
02896 {
02897   const PixRGB<double> A( A1 );
02898 
02899   // p[0] = h1  : p[1] = h2  : p[2] = s  : p[3] = v
02900   // A[0] = r : A[1] = g : A[2] = b
02901 
02902   double h = 0;
02903 
02904 // SEE PixelsCommonDef.H
02905 PIX_RGB_TO_HSV_COMMON(A[0],A[1],A[2],h,p[2],p[3],false)
02906 // SEE PixelsCommonDef.H
02907 PIX_HSV_TO_H2SV1_COMMON(h,p[2],p[0],p[1])
02908 
02909 }
02910 
02911 // ######################################################################
02912 template <class T>
02913 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixHSV<T2>& A1)
02914   : Pixels<T,4>()
02915 {
02916   const PixHSV<double> A( A1 );
02917 
02918   // p[0] = h1  : p[1] = h2  : p[2] = s  : p[3] = v
02919   // A[0] = h : A[1] = s : A[2] = v
02920 
02921   // demoduloize hue into two components
02922 
02923 // SEE PixelsCommonDef.H
02924   PIX_HSV_TO_H2SV1_COMMON(A[0],A[1],p[0],p[1])
02925 
02926   p[2] = clamped_convert<T>(A[1]/HSV_S_UPPER);
02927   p[3] = clamped_convert<T>(A[2]/HSV_V_UPPER);
02928 }
02929 
02930 // ######################################################################
02931 template <class T>
02932 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixYIQ<T2>& A1)
02933   : Pixels<T,4>()
02934 {
02935   const PixYIQ<double>   A( A1 );
02936   const PixRGB<double>   B( A );
02937   const PixH2SV1<double> C( B );
02938   pix_helper::clamped_assign_4(*this, C);
02939 }
02940 
02941 // ######################################################################
02942 template <class T>
02943 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixHSL<T2>& A1)
02944   : Pixels<T,4>()
02945 {
02946   const PixHSL<double> A( A1 );
02947 
02948   // p[0] = h1  : p[1] = h2  : p[2] = s  : p[3] = v
02949   // A[0] = h : A[1] = s : A[2] = l
02950 
02951   // demoduloize hue into two components
02952 
02953 // SEE PixelsCommonDef.H
02954 PIX_HSV_TO_H2SV1_COMMON(A[0],A[1],p[0],p[1])
02955 
02956   p[2] = clamped_convert<T>(A[1]/HSL_S_UPPER);
02957   p[3] = clamped_convert<T>(A[2]/HSL_L_UPPER);
02958 }
02959 
02960 // ######################################################################
02961 template <class T>
02962 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixH2SV1<T2>& A)
02963   : Pixels<T,4>()
02964 {
02965   pix_helper::clamped_assign_4(*this, A);
02966 }
02967 
02968 // ######################################################################
02969 template <class T>
02970 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixH2SV2<T2>& A1)
02971   : Pixels<T,4>()
02972 {
02973   const PixH2SV2<double> A( A1 );
02974   const PixRGB<double>   B( A );
02975   const PixH2SV1<double> C( B );
02976   pix_helper::clamped_assign_4(*this, C);
02977 }
02978 
02979 // ######################################################################
02980 template <class T>
02981 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixH2SV3<T2>& A1)
02982   : Pixels<T,4>()
02983 {
02984   const PixH2SV3<double> A( A1 );
02985   const PixRGB<double>   B( A );
02986   const PixH2SV1<double> C( B );
02987   pix_helper::clamped_assign_4(*this, C);
02988 }
02989 
02990 // ######################################################################
02991 template <class T>
02992 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixHyper<T2,4>& A)
02993   : Pixels<T,4>()
02994 {
02995   pix_helper::clamped_assign_4(*this, A);
02996 }
02997 
02998 // ######################################################################
02999 // Standard Constructors / Destructor
03000 // ######################################################################
03001 
03002 template <class T>
03003 inline PixH2SV1<T>::PixH2SV1() : Pixels<T,4>()
03004 {}
03005 
03006 // ######################################################################
03007 template <class T>
03008 inline PixH2SV1<T>::~PixH2SV1()
03009 {}
03010 
03011 // ######################################################################
03012 template <class T>
03013 inline PixH2SV1<T>::PixH2SV1(T val) : Pixels<T,4>(val)
03014 {}
03015 
03016 // ######################################################################
03017 template <class T>
03018 inline PixH2SV1<T>::PixH2SV1(const PixH2SV1<T>& pix) : Pixels<T,4>(pix)
03019 {}
03020 
03021 
03022 // ######################################################################
03023 // Special methods for this class
03024 // ######################################################################
03025 
03026 template <class T>
03027 inline void PixH2SV1<T>::getH2SV1(T& h1, T& h2, T& s, T& v) const
03028 {
03029   h1 = p[0]; h2 = p[1]; s = p[2]; v = p[3];
03030 }
03031 
03032 // ######################################################################
03033 template <class T>
03034 inline PixH2SV1<T>::PixH2SV1(const T H1val, const T H2val, const T Sval, const T Vval) : Pixels<T,4>()
03035 {
03036   p[0] = H1val; p[1] = H2val; p[2] = Sval; p[3] = Vval;
03037 }
03038 
03039 // ######################################################################
03040 template <class T>
03041 template <class T2, class T3, class T4, class T5> inline
03042 PixH2SV1<T>::PixH2SV1(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ) : Pixels<T,4>()
03043 {
03044   p[0] = clamped_convert<T>(H1val);
03045   p[1] = clamped_convert<T>(H2val);
03046   p[2] = clamped_convert<T>(Sval);
03047   p[3] = clamped_convert<T>(Vval);
03048 }
03049 
03050 // ######################################################################
03051 template <class T>
03052 inline T PixH2SV1<T>::H1() const
03053 {
03054   return p[0];
03055 }
03056 
03057 // ######################################################################
03058 template <class T>
03059 inline T PixH2SV1<T>::H2() const
03060 {
03061   return p[1];
03062 }
03063 
03064 // ######################################################################
03065 template <class T>
03066 inline T PixH2SV1<T>::S() const
03067 {
03068   return p[2];
03069 }
03070 
03071 // ######################################################################
03072 template <class T>
03073 inline T PixH2SV1<T>::V() const
03074 {
03075   return p[3];
03076 }
03077 
03078 // ######################################################################
03079 template <class T>
03080 template <class T2> inline void PixH2SV1<T>::setH1(const T2 hh1)
03081 {
03082   p[0] = clamped_convert<T>(hh1);
03083 }
03084 // ######################################################################
03085 template <class T>
03086 template <class T2> inline void PixH2SV1<T>::setH2(const T2 hh2)
03087 {
03088   p[1] = clamped_convert<T>(hh2);
03089 }
03090 // ######################################################################
03091 template <class T>
03092 template <class T2> inline void PixH2SV1<T>::setS(const T2 ss)
03093 {
03094   p[2] = clamped_convert<T>(ss);
03095 }
03096 // ######################################################################
03097 template <class T>
03098 template <class T2> inline void PixH2SV1<T>::setV(const T2 vv)
03099 {
03100   p[3] = clamped_convert<T>(vv);
03101 }
03102 
03103 // ######################################################################
03104 // ######################################################################
03105 // Pixels H2SV2
03106 // ######################################################################
03107 // ######################################################################
03108 
03109 // ######################################################################
03110 // constructors for where Pix<T> != Pix<T2> - with conversion
03111 // ######################################################################
03112 
03113 template <class T>
03114 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixRGB<T2>& A1)
03115   : Pixels<T,4>()
03116 {
03117 
03118   const PixRGB<double> A( A1 );
03119 
03120   // p[0] = h1  : p[1] = h2  : p[2] = s  : p[3] = v
03121   // A[0] = r : A[1] = g : A[2] = b
03122   double h = 0;
03123 
03124 // SEE PixelsCommonDef.H
03125 PIX_RGB_TO_HSV_COMMON(A[0],A[1],A[2],h,p[2],p[3],false)
03126 // SEE PixelsCommonDef.H
03127 PIX_HSV_TO_H2SV2_COMMON(h,p[2],p[0],p[1])
03128 }
03129 
03130 // ######################################################################
03131 template <class T>
03132 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixHSV<T2>& A1)
03133   : Pixels<T,4>()
03134 {
03135   const PixH2SV2<double> A( A1 );
03136 
03137   // p[0] = h1  : p[1] = h2  : p[2] = s  : p[3] = v
03138   // A[0] = h : A[1] = s : A[2] = v
03139 
03140   // demoduloize hue into two components B/Y and R/G like
03141 
03142 // SEE PixelsCommonDef.H
03143 PIX_HSV_TO_H2SV2_COMMON(A[0],A[1],p[0],p[1])
03144 
03145   p[2] = clamped_convert<T>(A[1]/HSV_S_UPPER);
03146   p[3] = clamped_convert<T>(A[2]/HSV_V_UPPER);
03147 }
03148 
03149 // ######################################################################
03150 template <class T>
03151 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixYIQ<T2>& A1)
03152   : Pixels<T,4>()
03153 {
03154   const PixYIQ<double>   A( A1 );
03155   const PixRGB<double>   B( A );
03156   const PixH2SV2<double> C( B ); // FIXME shouldn't this be PixH2SV2???
03157   pix_helper::clamped_assign_4(*this, C);
03158 }
03159 
03160 // ######################################################################
03161 template <class T>
03162 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixHSL<T2>& A1)
03163   : Pixels<T,4>()
03164 {
03165   const PixH2SV2<double> A( A1 );
03166 
03167   // p[0] = h1  : p[1] = h2  : p[2] = s  : p[3] = v
03168   // A[0] = h : A[1] = s : A[2] = l
03169 
03170   // demoduloize hue into two components B/Y and R/G like
03171 
03172 // SEE PixelsCommonDef.H
03173 PIX_HSV_TO_H2SV2_COMMON(A[0],A[1],p[0],p[1])
03174 
03175   p[2] = clamped_convert<T>(A[1]/HSL_S_UPPER);
03176   p[3] = clamped_convert<T>(A[2]/HSL_L_UPPER);
03177 }
03178 
03179 // ######################################################################
03180 template <class T>
03181 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixH2SV1<T2>& A1)
03182   : Pixels<T,4>()
03183 {
03184   const PixH2SV1<double> A( A1 );
03185   const PixRGB<double>   B( A );
03186   const PixH2SV2<double> C( B ); // FIXME shouldn't this be PixH2SV2???
03187   pix_helper::clamped_assign_4(*this, C);
03188 }
03189 
03190 // ######################################################################
03191 template <class T>
03192 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixH2SV2<T2>& A)
03193   : Pixels<T,4>()
03194 {
03195   pix_helper::clamped_assign_4(*this, A);
03196 }
03197 
03198 // ######################################################################
03199 template <class T>
03200 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixH2SV3<T2>& A1)
03201   : Pixels<T,4>()
03202 {
03203   const PixH2SV3<double> A( A1 );
03204   const PixRGB<double>   B( A );
03205   const PixH2SV2<double> C( B ); // FIXME shouldn't this be PixH2SV2???
03206   pix_helper::clamped_assign_4(*this, C);
03207 }
03208 
03209 // ######################################################################
03210 template <class T>
03211 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixHyper<T2,4>& A)
03212   : Pixels<T,4>()
03213 {
03214   pix_helper::clamped_assign_4(*this, A);
03215 }
03216 
03217 // ######################################################################
03218 // Standard Constructors / Destructor
03219 // ######################################################################
03220 
03221 template <class T>
03222 inline PixH2SV2<T>::PixH2SV2() : Pixels<T,4>()
03223 {}
03224 
03225 // ######################################################################
03226 template <class T>
03227 inline PixH2SV2<T>::~PixH2SV2()
03228 {}
03229 
03230 // ######################################################################
03231 template <class T>
03232 inline PixH2SV2<T>::PixH2SV2(const T val) : Pixels<T,4>(val)
03233 {}
03234 
03235 // ######################################################################
03236 template <class T>
03237 inline PixH2SV2<T>::PixH2SV2(const PixH2SV2<T>& pix) : Pixels<T,4>(pix)
03238 {}
03239 
03240 // ######################################################################
03241 // Special methods for this class
03242 // ######################################################################
03243 
03244 template <class T>
03245 inline void PixH2SV2<T>::getH2SV2(T& h1, T& h2, T& s, T& v) const
03246 {
03247   h1 = p[0]; h2 = p[1]; s = p[2]; v = p[3];
03248 }
03249 
03250 template <class T>
03251 inline PixH2SV2<T>::PixH2SV2(const T H1val, const T H2val, const T Sval, const T Vval) : Pixels<T,4>()
03252 {
03253   p[0] = H1val; p[1] = H2val; p[2] = Sval; p[3] = Vval;
03254 }
03255 
03256 // ######################################################################
03257 template <class T> template <class T2, class T3, class T4, class T5> inline
03258 PixH2SV2<T>::PixH2SV2(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ) : Pixels<T,4>()
03259 {
03260   p[0] = clamped_convert<T>(H1val);
03261   p[1] = clamped_convert<T>(H2val);
03262   p[2] = clamped_convert<T>(Sval);
03263   p[3] = clamped_convert<T>(Vval);
03264 }
03265 
03266 // ######################################################################
03267 template <class T>
03268 inline T PixH2SV2<T>::H1() const
03269 {
03270   return p[0];
03271 }
03272 
03273 // ######################################################################
03274 template <class T>
03275 inline T PixH2SV2<T>::H2() const
03276 {
03277   return p[1];
03278 }
03279 
03280 // ######################################################################
03281 template <class T>
03282 inline T PixH2SV2<T>::S() const
03283 {
03284   return p[2];
03285 }
03286 
03287 // ######################################################################
03288 template <class T>
03289 inline T PixH2SV2<T>::V() const
03290 {
03291   return p[3];
03292 }
03293 
03294 // ######################################################################
03295 template <class T>
03296 template <class T2> inline void PixH2SV2<T>::setH1(const T2 hh1)
03297 {
03298   p[0] = clamped_convert<T>(hh1);
03299 }
03300 // ######################################################################
03301 template <class T>
03302 template <class T2> inline void PixH2SV2<T>::setH2(const T2 hh2)
03303 {
03304   p[1] = clamped_convert<T>(hh2);
03305 }
03306 // ######################################################################
03307 template <class T>
03308 template <class T2> inline void PixH2SV2<T>::setS(const T2 ss)
03309 {
03310   p[2] = clamped_convert<T>(ss);
03311 }
03312 // ######################################################################
03313 template <class T>
03314 template <class T2> inline void PixH2SV2<T>::setV(const T2 vv)
03315 {
03316   p[3] = clamped_convert<T>(vv);
03317 }
03318 
03319 // ######################################################################
03320 // ######################################################################
03321 // Pixels H2SV3
03322 // ######################################################################
03323 // ######################################################################
03324 
03325 // ######################################################################
03326 // constructors for where Pix<T> != Pix<T2> - with conversion
03327 // ######################################################################
03328 
03329 // ######################################################################
03330 template <class T>
03331 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixYIQ<T2>& A1)
03332   : Pixels<T,4>()
03333 {
03334   const PixYIQ<double> A( A1 );
03335   const PixRGB<double>   B( A );
03336   const PixH2SV3<double> C( B );
03337   pix_helper::clamped_assign_4(*this, C);
03338 }
03339 
03340 // ######################################################################
03341 template <class T>
03342 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixH2SV1<T2>& A1)
03343   : Pixels<T,4>()
03344 {
03345   const PixH2SV1<double> A( A1 );
03346   const PixRGB<double>   B( A );
03347   const PixH2SV3<double> C( B );
03348   pix_helper::clamped_assign_4(*this, C);
03349 }
03350 
03351 // ######################################################################
03352 template <class T>
03353 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixH2SV2<T2>& A1)
03354   : Pixels<T,4>()
03355 {
03356   const PixH2SV2<double> A( A1 );
03357   const PixRGB<double>   B( A );
03358   const PixH2SV3<double> C( B );
03359   pix_helper::clamped_assign_4(*this, C);
03360 }
03361 
03362 // ######################################################################
03363 template <class T>
03364 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixH2SV3<T2>& A)
03365   : Pixels<T,4>()
03366 {
03367   pix_helper::clamped_assign_4(*this, A);
03368 }
03369 
03370 // ######################################################################
03371 template <class T>
03372 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixHyper<T2,4>& A)
03373   : Pixels<T,4>()
03374 {
03375   pix_helper::clamped_assign_4(*this, A);
03376 }
03377 
03378 // ######################################################################
03379 // Standard Constructors / Destructor
03380 // ######################################################################
03381 
03382 template <class T>
03383 inline PixH2SV3<T>::PixH2SV3() : Pixels<T,4>()
03384 {}
03385 
03386 // ######################################################################
03387 template <class T>
03388 inline PixH2SV3<T>::~PixH2SV3()
03389 {}
03390 
03391 // ######################################################################
03392 template <class T>
03393 inline PixH2SV3<T>::PixH2SV3(const T val) : Pixels<T,4>(val)
03394 {}
03395 
03396 // ######################################################################
03397 template <class T>
03398 inline PixH2SV3<T>::PixH2SV3(const PixH2SV3<T>& pix) : Pixels<T,4>(pix)
03399 {}
03400 
03401 // ######################################################################
03402 // Special methods for this class
03403 // ######################################################################
03404 
03405 template <class T>
03406 inline void PixH2SV3<T>::getH2SV3(T& h1, T& h2, T& s, T& v) const
03407 {
03408   h1 = p[0]; h2 = p[1]; s = p[2]; v = p[3];
03409 }
03410 
03411 template <class T>
03412 inline PixH2SV3<T>::PixH2SV3(const T H1val, const T H2val, const T Sval, const T Vval) : Pixels<T,4>()
03413 {
03414   p[0] = H1val; p[1] = H2val; p[2] = Sval; p[3] = Vval;
03415 }
03416 
03417 // ######################################################################
03418 template <class T> template <class T2, class T3, class T4, class T5> inline
03419 PixH2SV3<T>::PixH2SV3(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ) : Pixels<T,4>()
03420 {
03421   p[0] = clamped_convert<T>(H1val);
03422   p[1] = clamped_convert<T>(H2val);
03423   p[2] = clamped_convert<T>(Sval);
03424   p[3] = clamped_convert<T>(Vval);
03425 }
03426 
03427 // ######################################################################
03428 template <class T>
03429 inline T PixH2SV3<T>::H1() const
03430 {
03431   return p[0];
03432 }
03433 
03434 // ######################################################################
03435 template <class T>
03436 inline T PixH2SV3<T>::H2() const
03437 {
03438   return p[1];
03439 }
03440 
03441 // ######################################################################
03442 template <class T>
03443 inline T PixH2SV3<T>::S() const
03444 {
03445   return p[2];
03446 }
03447 
03448 // ######################################################################
03449 template <class T>
03450 inline T PixH2SV3<T>::V() const
03451 {
03452   return p[3];
03453 }
03454 
03455 // ######################################################################
03456 template <class T>
03457 template <class T2> inline void PixH2SV3<T>::setH1(const T2 hh1)
03458 {
03459   p[0] = clamped_convert<T>(hh1);
03460 }
03461 // ######################################################################
03462 template <class T>
03463 template <class T2> inline void PixH2SV3<T>::setH2(const T2 hh2)
03464 {
03465   p[1] = clamped_convert<T>(hh2);
03466 }
03467 // ######################################################################
03468 template <class T>
03469 template <class T2> inline void PixH2SV3<T>::setS(const T2 ss)
03470 {
03471   p[2] = clamped_convert<T>(ss);
03472 }
03473 // ######################################################################
03474 template <class T>
03475 template <class T2> inline void PixH2SV3<T>::setV(const T2 vv)
03476 {
03477   p[3] = clamped_convert<T>(vv);
03478 }
03479 
03480 // ######################################################################
03481 // ######################################################################
03482 // Pixels Hyper
03483 // ######################################################################
03484 // ######################################################################
03485 
03486 // ######################################################################
03487 // constructors for where Pix<T> != Pix<T2> - with conversion
03488 // ######################################################################
03489 
03490 template <class T, size_t dim>
03491 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixRGB<T2>& A)
03492   : Pixels<T,dim>()
03493 {
03494   pix_helper::clamped_assign_3(*this, A);
03495 }
03496 
03497 // ######################################################################
03498 template <class T, size_t dim>
03499 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixHSV<T2>& A)
03500   : Pixels<T,dim>()
03501 {
03502   pix_helper::clamped_assign_3(*this, A);
03503 }
03504 
03505 // ######################################################################
03506 template <class T, size_t dim>
03507 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixJpegYUV<T2>& A)
03508   : Pixels<T,dim>()
03509 {
03510   pix_helper::clamped_assign_3(*this, A);
03511 }
03512 
03513 // ######################################################################
03514 template <class T, size_t dim>
03515 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixVideoYUV<T2>& A)
03516   : Pixels<T,dim>()
03517 {
03518   pix_helper::clamped_assign_3(*this, A);
03519 }
03520 
03521 // ######################################################################
03522 template <class T, size_t dim>
03523 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixYIQ<T2>& A)
03524   : Pixels<T,dim>()
03525 {
03526   pix_helper::clamped_assign_3(*this, A);
03527 }
03528 
03529 // ######################################################################
03530 template <class T, size_t dim>
03531 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixHSL<T2>& A)
03532   : Pixels<T,dim>()
03533 {
03534   pix_helper::clamped_assign_3(*this, A);
03535 }
03536 
03537 // ######################################################################
03538 template <class T, size_t dim>
03539 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixH2SV1<T2>& A)
03540   : Pixels<T,dim>()
03541 {
03542   pix_helper::clamped_assign_4(*this, A);
03543 }
03544 
03545 // ######################################################################
03546 template <class T, size_t dim>
03547 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixH2SV2<T2>& A)
03548   : Pixels<T,dim>()
03549 {
03550   pix_helper::clamped_assign_4(*this, A);
03551 }
03552 
03553 // ######################################################################
03554 template <class T, size_t dim>
03555 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixH2SV3<T2>& A)
03556   : Pixels<T,dim>()
03557 {
03558   pix_helper::clamped_assign_4(*this, A);
03559 }
03560 
03561 // ######################################################################
03562 template <class T, size_t dim>
03563 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixHyper<T2,dim>& A)
03564   : Pixels<T,dim>()
03565 {
03566   pix_helper::clamped_assign_n(*this, A);
03567 }
03568 
03569 // ######################################################################
03570 // Standard Constructors / Destructor
03571 // ######################################################################
03572 
03573 template <class T, size_t dim>
03574 inline PixHyper<T,dim>::PixHyper() : Pixels<T,dim>()
03575 {}
03576 
03577 // ######################################################################
03578 template <class T, size_t dim>
03579 inline PixHyper<T,dim>::~PixHyper()
03580 {}
03581 
03582 // ######################################################################
03583 template <class T, size_t dim>
03584 inline PixHyper<T,dim>::PixHyper(const T val) : Pixels<T,dim>(val)
03585 {}
03586 
03587 // ######################################################################
03588 template <class T, size_t dim>
03589 inline PixHyper<T,dim>::PixHyper(const PixHyper<T,dim>& pix) : Pixels<T,dim>(pix)
03590 {}
03591 
03592 
03593 // ######################################################################
03594 // ######################################################################
03595 // Pixels DKL
03596 // ######################################################################
03597 // ######################################################################
03598 
03599 template <class T>
03600 template <class T2> inline PixDKL<T>::PixDKL(const PixRGB<T2>& A1)
03601   : Pixels<T,3>()
03602 {
03603   // bunch of constants used for RGB -> DKL conversion:
03604   static const double lut_rgb[256*3]  = {
03605     0.024935, 0.0076954, 0.042291,
03606     0.024974, 0.0077395, 0.042346,
03607     0.025013, 0.0077836, 0.042401,
03608     0.025052, 0.0078277, 0.042456,
03609     0.025091, 0.0078717, 0.042511,
03610     0.02513, 0.0079158, 0.042566,
03611     0.025234, 0.007992, 0.042621,
03612     0.025338, 0.0080681, 0.042676,
03613     0.025442, 0.0081443, 0.042731,
03614     0.025545, 0.0082204, 0.042786,
03615     0.025649, 0.0082966, 0.042841,
03616     0.025747, 0.0084168, 0.042952,
03617     0.025844, 0.0085371, 0.043062,
03618     0.025942, 0.0086573, 0.043172,
03619     0.026039, 0.0087776, 0.043282,
03620     0.026136, 0.0088978, 0.043392,
03621     0.026234, 0.0090581, 0.043502,
03622     0.026331, 0.0092184, 0.043612,
03623     0.026429, 0.0093788, 0.043722,
03624     0.026526, 0.0095391, 0.043833,
03625     0.026623, 0.0096994, 0.043943,
03626     0.026818, 0.0099198, 0.044141,
03627     0.027013, 0.01014, 0.044339,
03628     0.027208, 0.010361, 0.044537,
03629     0.027403, 0.010581, 0.044736,
03630     0.027597, 0.010802, 0.044934,
03631     0.027857, 0.010994, 0.04522,
03632     0.028117, 0.011186, 0.045507,
03633     0.028377, 0.011379, 0.045793,
03634     0.028636, 0.011571, 0.046079,
03635     0.028896, 0.011764, 0.046366,
03636     0.029104, 0.012068, 0.046652,
03637     0.029312, 0.012373, 0.046938,
03638     0.029519, 0.012677, 0.047225,
03639     0.029727, 0.012982, 0.047511,
03640     0.029935, 0.013287, 0.047797,
03641     0.030273, 0.013663, 0.048326,
03642     0.03061, 0.01404, 0.048855,
03643     0.030948, 0.014417, 0.049383,
03644     0.031286, 0.014794, 0.049912,
03645     0.031623, 0.01517, 0.050441,
03646     0.032156, 0.015707, 0.051035,
03647     0.032688, 0.016244, 0.05163,
03648     0.033221, 0.016782, 0.052225,
03649     0.033753, 0.017319, 0.052819,
03650     0.034286, 0.017856, 0.053414,
03651     0.034961, 0.018693, 0.054493,
03652     0.035636, 0.019531, 0.055573,
03653     0.036312, 0.020369, 0.056652,
03654     0.036987, 0.021206, 0.057731,
03655     0.037662, 0.022044, 0.058811,
03656     0.038623, 0.023246, 0.060044,
03657     0.039584, 0.024449, 0.061278,
03658     0.040545, 0.025651, 0.062511,
03659     0.041506, 0.026854, 0.063744,
03660     0.042468, 0.028056, 0.064978,
03661     0.043857, 0.029659, 0.066806,
03662     0.045247, 0.031263, 0.068634,
03663     0.046636, 0.032866, 0.070463,
03664     0.048026, 0.034469, 0.072291,
03665     0.049416, 0.036072, 0.074119,
03666     0.051221, 0.038156, 0.076476,
03667     0.053026, 0.04024, 0.078833,
03668     0.054831, 0.042325, 0.081189,
03669     0.056636, 0.044409, 0.083546,
03670     0.058442, 0.046493, 0.085903,
03671     0.06039, 0.048737, 0.087996,
03672     0.062338, 0.050982, 0.090088,
03673     0.064286, 0.053226, 0.092181,
03674     0.066234, 0.055471, 0.094273,
03675     0.068182, 0.057715, 0.096366,
03676     0.070519, 0.06012, 0.098921,
03677     0.072857, 0.062525, 0.10148,
03678     0.075195, 0.06493, 0.10403,
03679     0.077532, 0.067335, 0.10659,
03680     0.07987, 0.069739, 0.10914,
03681     0.082208, 0.072345, 0.11176,
03682     0.084545, 0.07495, 0.11438,
03683     0.086883, 0.077555, 0.117,
03684     0.089221, 0.08016, 0.11963,
03685     0.091558, 0.082766, 0.12225,
03686     0.094026, 0.085611, 0.12533,
03687     0.096494, 0.088457, 0.12841,
03688     0.098961, 0.091303, 0.1315,
03689     0.10143, 0.094148, 0.13458,
03690     0.1039, 0.096994, 0.13767,
03691     0.10688, 0.10028, 0.14119,
03692     0.10987, 0.10357, 0.14471,
03693     0.11286, 0.10685, 0.14824,
03694     0.11584, 0.11014, 0.15176,
03695     0.11883, 0.11343, 0.15529,
03696     0.12208, 0.11695, 0.15903,
03697     0.12532, 0.12048, 0.16278,
03698     0.12857, 0.12401, 0.16652,
03699     0.13182, 0.12754, 0.17026,
03700     0.13506, 0.13106, 0.17401,
03701     0.1387, 0.13499, 0.17819,
03702     0.14234, 0.13892, 0.18238,
03703     0.14597, 0.14285, 0.18656,
03704     0.14961, 0.14677, 0.19075,
03705     0.15325, 0.1507, 0.19493,
03706     0.15727, 0.15519, 0.19956,
03707     0.1613, 0.15968, 0.20419,
03708     0.16532, 0.16417, 0.20881,
03709     0.16935, 0.16866, 0.21344,
03710     0.17338, 0.17315, 0.21806,
03711     0.17805, 0.17796, 0.22291,
03712     0.18273, 0.18277, 0.22775,
03713     0.1874, 0.18758, 0.2326,
03714     0.19208, 0.19238, 0.23744,
03715     0.19675, 0.19719, 0.24229,
03716     0.20156, 0.20224, 0.24758,
03717     0.20636, 0.20729, 0.25286,
03718     0.21117, 0.21234, 0.25815,
03719     0.21597, 0.21739, 0.26344,
03720     0.22078, 0.22244, 0.26872,
03721     0.2261, 0.22806, 0.27423,
03722     0.23143, 0.23367, 0.27974,
03723     0.23675, 0.23928, 0.28524,
03724     0.24208, 0.24489, 0.29075,
03725     0.2474, 0.2505, 0.29626,
03726     0.25299, 0.25651, 0.3022,
03727     0.25857, 0.26253, 0.30815,
03728     0.26416, 0.26854, 0.3141,
03729     0.26974, 0.27455, 0.32004,
03730     0.27532, 0.28056, 0.32599,
03731     0.28156, 0.28697, 0.33238,
03732     0.28779, 0.29339, 0.33877,
03733     0.29403, 0.2998, 0.34515,
03734     0.30026, 0.30621, 0.35154,
03735     0.30649, 0.31263, 0.35793,
03736     0.3126, 0.31904, 0.36388,
03737     0.3187, 0.32545, 0.36982,
03738     0.32481, 0.33186, 0.37577,
03739     0.33091, 0.33828, 0.38172,
03740     0.33701, 0.34469, 0.38767,
03741     0.34325, 0.3511, 0.39361,
03742     0.34948, 0.35752, 0.39956,
03743     0.35571, 0.36393, 0.40551,
03744     0.36195, 0.37034, 0.41145,
03745     0.36818, 0.37675, 0.4174,
03746     0.37429, 0.38317, 0.42313,
03747     0.38039, 0.38958, 0.42885,
03748     0.38649, 0.39599, 0.43458,
03749     0.3926, 0.4024, 0.44031,
03750     0.3987, 0.40882, 0.44604,
03751     0.40494, 0.41523, 0.45198,
03752     0.41117, 0.42164, 0.45793,
03753     0.4174, 0.42806, 0.46388,
03754     0.42364, 0.43447, 0.46982,
03755     0.42987, 0.44088, 0.47577,
03756     0.43623, 0.44689, 0.48128,
03757     0.4426, 0.45291, 0.48678,
03758     0.44896, 0.45892, 0.49229,
03759     0.45532, 0.46493, 0.4978,
03760     0.46169, 0.47094, 0.5033,
03761     0.46792, 0.47695, 0.50837,
03762     0.47416, 0.48297, 0.51344,
03763     0.48039, 0.48898, 0.5185,
03764     0.48662, 0.49499, 0.52357,
03765     0.49286, 0.501, 0.52863,
03766     0.49805, 0.50701, 0.53392,
03767     0.50325, 0.51303, 0.53921,
03768     0.50844, 0.51904, 0.54449,
03769     0.51364, 0.52505, 0.54978,
03770     0.51883, 0.53106, 0.55507,
03771     0.52442, 0.53667, 0.55969,
03772     0.53, 0.54228, 0.56432,
03773     0.53558, 0.5479, 0.56894,
03774     0.54117, 0.55351, 0.57357,
03775     0.54675, 0.55912, 0.57819,
03776     0.55182, 0.56433, 0.58304,
03777     0.55688, 0.56954, 0.58789,
03778     0.56195, 0.57475, 0.59273,
03779     0.56701, 0.57996, 0.59758,
03780     0.57208, 0.58517, 0.60242,
03781     0.57675, 0.58998, 0.60639,
03782     0.58143, 0.59479, 0.61035,
03783     0.5861, 0.5996, 0.61432,
03784     0.59078, 0.60441, 0.61828,
03785     0.59545, 0.60922, 0.62225,
03786     0.60065, 0.61403, 0.62709,
03787     0.60584, 0.61884, 0.63194,
03788     0.61104, 0.62365, 0.63678,
03789     0.61623, 0.62846, 0.64163,
03790     0.62143, 0.63327, 0.64648,
03791     0.62584, 0.63808, 0.65088,
03792     0.63026, 0.64289, 0.65529,
03793     0.63468, 0.6477, 0.65969,
03794     0.63909, 0.65251, 0.6641,
03795     0.64351, 0.65731, 0.6685,
03796     0.64857, 0.66132, 0.67269,
03797     0.65364, 0.66533, 0.67687,
03798     0.6587, 0.66934, 0.68106,
03799     0.66377, 0.67335, 0.68524,
03800     0.66883, 0.67735, 0.68943,
03801     0.67273, 0.68136, 0.69361,
03802     0.67662, 0.68537, 0.6978,
03803     0.68052, 0.68938, 0.70198,
03804     0.68442, 0.69339, 0.70617,
03805     0.68831, 0.69739, 0.71035,
03806     0.69221, 0.7022, 0.7141,
03807     0.6961, 0.70701, 0.71784,
03808     0.7, 0.71182, 0.72159,
03809     0.7039, 0.71663, 0.72533,
03810     0.70779, 0.72144, 0.72907,
03811     0.71169, 0.72505, 0.73348,
03812     0.71558, 0.72866, 0.73789,
03813     0.71948, 0.73226, 0.74229,
03814     0.72338, 0.73587, 0.7467,
03815     0.72727, 0.73948, 0.7511,
03816     0.73247, 0.74349, 0.75507,
03817     0.73766, 0.74749, 0.75903,
03818     0.74286, 0.7515, 0.763,
03819     0.74805, 0.75551, 0.76696,
03820     0.75325, 0.75952, 0.77093,
03821     0.75714, 0.76393, 0.77599,
03822     0.76104, 0.76834, 0.78106,
03823     0.76494, 0.77275, 0.78612,
03824     0.76883, 0.77715, 0.79119,
03825     0.77273, 0.78156, 0.79626,
03826     0.77792, 0.78677, 0.80132,
03827     0.78312, 0.79198, 0.80639,
03828     0.78831, 0.79719, 0.81145,
03829     0.79351, 0.8024, 0.81652,
03830     0.7987, 0.80762, 0.82159,
03831     0.80519, 0.81283, 0.82687,
03832     0.81169, 0.81804, 0.83216,
03833     0.81818, 0.82325, 0.83744,
03834     0.82468, 0.82846, 0.84273,
03835     0.83117, 0.83367, 0.84802,
03836     0.83636, 0.83888, 0.85286,
03837     0.84156, 0.84409, 0.85771,
03838     0.84675, 0.8493, 0.86256,
03839     0.85195, 0.85451, 0.8674,
03840     0.85714, 0.85972, 0.87225,
03841     0.86364, 0.86613, 0.87819,
03842     0.87013, 0.87255, 0.88414,
03843     0.87662, 0.87896, 0.89009,
03844     0.88312, 0.88537, 0.89604,
03845     0.88961, 0.89178, 0.90198,
03846     0.8961, 0.8986, 0.90947,
03847     0.9026, 0.90541, 0.91696,
03848     0.90909, 0.91222, 0.92445,
03849     0.91558, 0.91904, 0.93194,
03850     0.92208, 0.92585, 0.93943,
03851     0.92857, 0.93307, 0.94493,
03852     0.93506, 0.94028, 0.95044,
03853     0.94156, 0.94749, 0.95595,
03854     0.94805, 0.95471, 0.96145,
03855     0.95455, 0.96192, 0.96696,
03856     0.96364, 0.96954, 0.97357,
03857     0.97273, 0.97715, 0.98018,
03858     0.98182, 0.98477, 0.98678,
03859     0.99091, 0.99238, 0.99339,
03860     1, 1, 1 };
03861 
03862   static const double lms0[3] = { 34.918538957799996, 19.314796676499999, 0.585610818500000 };
03863 
03864   static const double m[9] = { 18.32535,  44.60077,   7.46216,
03865                                4.09544,  28.20135,   6.66066,
03866                                0.02114,   0.10325,   1.05258 };
03867 
03868   static const double fac = 1.0 / (lms0[0] + lms0[1]);
03869 
03870   static const double mm[9] = {
03871     sqrt(3.0)*fac, sqrt(3.0)*fac, 0.0,
03872     sqrt(lms0[0]*lms0[0]+lms0[1]*lms0[1])/lms0[0]*fac, -sqrt(lms0[0]*lms0[0]+lms0[1]*lms0[1])/lms0[1]*fac, 0.0,
03873     -fac, -fac, (lms0[0] + lms0[1]) / lms0[2] * fac };
03874 
03875   // convert RGB values to bytes, with clamping:
03876   const PixRGB<byte> A(A1);
03877 
03878   // do a lookup RGB -> rgb:
03879   const double aa1 = lut_rgb[A[0] * 3];
03880   const double aa2 = lut_rgb[A[1] * 3 + 1];
03881   const double aa3 = lut_rgb[A[2] * 3 + 2];
03882 
03883   // now convert to LMS:
03884   const double lms1 = m[0] * aa1 + m[1] * aa2 + m[2] * aa3 - lms0[0];
03885   const double lms2 = m[3] * aa1 + m[4] * aa2 + m[5] * aa3 - lms0[1];
03886   const double lms3 = m[6] * aa1 + m[7] * aa2 + m[8] * aa3 - lms0[2];
03887 
03888   // finally to DKL:
03889   const double dkl1 = mm[0] * lms1 + mm[1] * lms2 + mm[2] * lms3;
03890   const double dkl2 = mm[3] * lms1 + mm[4] * lms2 + mm[5] * lms3;
03891   const double dkl3 = mm[6] * lms1 + mm[7] * lms2 + mm[8] * lms3;
03892 
03893   // finally to DKLn:
03894   p[0] = clamped_convert<T>(dkl1 * 0.5774);
03895   p[1] = clamped_convert<T>(dkl2 * 2.7525);
03896   p[2] = clamped_convert<T>(dkl3 * 0.4526);
03897 }
03898 
03899 // ######################################################################
03900 // Standard Constructors / Destrcutor
03901 // ######################################################################
03902 
03903 template <class T>
03904 inline PixDKL<T>::PixDKL() : Pixels<T,3>()
03905 {}
03906 
03907 // ######################################################################
03908 template <class T>
03909 inline PixDKL<T>::~PixDKL()
03910 {}
03911 
03912 // ######################################################################
03913 template <class T>
03914 inline PixDKL<T>::PixDKL(const T val) : Pixels<T,3>(val)
03915 {}
03916 
03917 // ######################################################################
03918 template <class T>
03919 inline PixDKL<T>::PixDKL(const PixDKL<T>& pix) : Pixels<T,3>(pix)
03920 {}
03921 
03922 // ######################################################################
03923 template <class T>
03924 template <class T2> inline PixDKL<T>::PixDKL(const PixDKL<T2>& A1)
03925   : Pixels<T,3>()
03926 {
03927   p[0] = clamped_convert<T>(A1[0]);
03928   p[1] = clamped_convert<T>(A1[1]);
03929   p[2] = clamped_convert<T>(A1[2]);
03930 }
03931 
03932 // ######################################################################
03933 // Special methods for this class
03934 // ######################################################################
03935 
03936 template <class T>
03937 inline void PixDKL<T>::getDKL(T& d, T& k, T& l) const
03938 {
03939   d = p[0]; k = p[1]; l = p[2];
03940 }
03941 
03942 // ######################################################################
03943 template <class T>
03944 inline PixDKL<T>::PixDKL(const T Dval, const T Kval, const T Lval) : Pixels<T,3>()
03945 {
03946   p[0] = Dval; p[1] = Kval; p[2] = Lval;
03947 }
03948 
03949 // ######################################################################
03950 template <class T> template <class T2, class T3, class T4> inline
03951 PixDKL<T>::PixDKL(const T2 Dval, const T3 Kval, const T4 Lval) : Pixels<T,3>()
03952 {
03953   p[0] = clamped_convert<T>(Dval);
03954   p[1] = clamped_convert<T>(Kval);
03955   p[2] = clamped_convert<T>(Lval);
03956 }
03957 
03958 // ######################################################################
03959 template <class T>
03960 inline T PixDKL<T>::D() const
03961 {
03962   return p[0];
03963 }
03964 
03965 // ######################################################################
03966 template <class T>
03967 inline T PixDKL<T>::K() const
03968 {
03969   return p[1];
03970 }
03971 
03972 // ######################################################################
03973 template <class T>
03974 inline T PixDKL<T>::L() const
03975 {
03976   return p[2];
03977 }
03978 
03979 // ######################################################################
03980 template <class T>
03981 template <class T2> inline void PixDKL<T>::setD(const T2 dd)
03982 {
03983   p[0] = clamped_convert<T>(dd);
03984 }
03985 
03986 // ######################################################################
03987 template <class T>
03988 template <class T2> inline void PixDKL<T>::setK(const T2 kk)
03989 {
03990   p[1] = clamped_convert<T>(kk);
03991 }
03992 
03993 // ######################################################################
03994 template <class T>
03995 template <class T2> inline void PixDKL<T>::setL(const T2 ll)
03996 {
03997   p[2] = clamped_convert<T>(ll);
03998 }
03999 
04000 // ######################################################################
04001 // Specialize promote_trait for pixel types
04002 // ######################################################################
04003 
04004 /* The SPECIALIZE_PROMOTE_TRAIT macro is defined in
04005    Util/Promotions.H. Note that these SPECIALIZE_PROMOTE_TRAIT() macro
04006    calls should NOT go in Util/Promotions.H, since the Util/ directory
04007    is supposed to be independent of pixels, images, etc. */
04008 
04009 //! Quickie macro for escaping the comma out of a macro argument.
04010 #define LIST_2(p1, p2) p1, p2
04011 
04012 /* If you need to add a dim to a hyper pixel you can add it here */
04013 SPECIALIZE_PROMOTE_TRAIT(PixHyper, LIST_2(class T, size_t dim), LIST_2(, 3))
04014 SPECIALIZE_PROMOTE_TRAIT(PixHyper, LIST_2(class T, size_t dim), LIST_2(, 4))
04015 
04016 #undef LIST_2
04017 
04018 SPECIALIZE_PROMOTE_TRAIT(PixRGB, class T, )
04019 SPECIALIZE_PROMOTE_TRAIT(PixHSV, class T, )
04020 SPECIALIZE_PROMOTE_TRAIT(PixJpegYUV, class T, )
04021 SPECIALIZE_PROMOTE_TRAIT(PixVideoYUV, class T, )
04022 SPECIALIZE_PROMOTE_TRAIT(PixYIQ, class T, )
04023 SPECIALIZE_PROMOTE_TRAIT(PixHSL, class T, )
04024 SPECIALIZE_PROMOTE_TRAIT(PixH2SV1, class T, )
04025 SPECIALIZE_PROMOTE_TRAIT(PixH2SV2, class T, )
04026 SPECIALIZE_PROMOTE_TRAIT(PixH2SV3, class T, )
04027 SPECIALIZE_PROMOTE_TRAIT(PixDKL, class T, )
04028 
04029 #endif
Generated on Sun May 8 08:05:15 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3