Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

kino_plugin_utility.h

Go to the documentation of this file.
00001 /*
00002  * kino_plugin_utility.h -- Helper Utilities for Plugins
00003  * Copyright (C) 2002-2007 Timothy M. Shead <tshead@k-3d.com>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018  */
00019 
00020 #ifndef KINO_PLUGIN_UTILITY_H
00021 #define KINO_PLUGIN_UTILITY_H
00022 
00023 #include <cassert>
00024 #include <deque>
00025 #include <vector>
00026 #include <numeric>
00027 
00028 namespace kino
00029 {
00030 
00032 template<typename ArgType>
00033 ArgType clamp(const ArgType A, const ArgType MinVal, const ArgType MaxVal)
00034 {
00035         return std::min(std::max(A, MinVal), MaxVal);
00036 }
00037 
00039 template<typename ArgType>
00040 inline ArgType lerp(const ArgType A, const ArgType B, const double Mix)
00041 {
00042         return static_cast<ArgType>(A * (1.0 - Mix) + B * Mix);
00043 }
00044 
00045 inline double step(const double Edge, const double A)
00046 {
00047         return A < Edge ? 0.0 : 1.0;
00048 }
00049 
00050 inline double linearstep(const double Edge1, const double Edge2, const double A)
00051 {
00052         if(A < Edge1)
00053                 return 0.0;
00054                 
00055         if(A >= Edge2)
00056                 return 1.0;
00057                 
00058         return (A - Edge1) / (Edge2 - Edge1);
00059 }
00060 
00061 inline double smoothstep(const double Edge1, const double Edge2, const double A)
00062 {
00063         if(A < Edge1)
00064                 return 0.0;
00065                 
00066         if(A >= Edge2)
00067                 return 1.0;
00068                 
00069         double a = (A - Edge1) / (Edge2 - Edge1);
00070         
00071         return (a * a * (3 - 2 * a));
00072 }
00073 
00074 inline double pulse(const double Edge1, const double Edge2, const double A)
00075 {
00076         return step(Edge1, A) - step(Edge2, A);
00077 }
00078 
00079 inline double factorial(const unsigned int X)
00080 {
00081     double result = 1;
00082     
00083     for(unsigned int i = 2; i <= X; ++i)
00084         result *= i;
00085         
00086     return result;
00087 }
00088 
00090 template<typename PixelType>
00091 class convolve_filter
00092 {
00093 public:
00094     convolve_filter() :
00095         m_scale(0)
00096     {
00097     }
00098     
00099     void push_weight(const double Weight)
00100     {
00101         m_weights.push_back(Weight);
00102         m_values.resize(m_weights.size());
00103         
00104         m_scale = std::accumulate(m_weights.begin(), m_weights.end(), 0.0);
00105         if(m_scale)
00106             m_scale = 1.0 / m_scale;
00107     }
00108     
00109     unsigned int width()
00110     {
00111         return m_weights.size();
00112     }
00113     
00114     unsigned int neighbors()
00115     {
00116         return m_weights.size() / 2;
00117     }
00118     
00119     unsigned int middle()
00120     {
00121         return m_weights.size() / 2;
00122     }
00123     
00124     void push_value(const PixelType Value)
00125     {
00126         // Sanity checks ...
00127         assert(m_weights.size());
00128         assert(m_weights.size() == m_values.size());
00129         
00130         m_values.push_back(Value);
00131         m_values.pop_front();
00132     }
00133     
00134     PixelType get_value()
00135     {
00136         PixelType result;
00137         
00138         weight_collection_type::const_iterator weight = m_weights.begin();
00139         for(typename value_collection_type::iterator value = m_values.begin(); value != m_values.end(); ++value, ++weight)
00140             {
00141                 result.red += (value->red) * (*weight);
00142                 result.green += (value->green) * (*weight);
00143                 result.blue += (value->blue) * (*weight);
00144             }
00145             
00146         result.red *= m_scale;
00147         result.green *= m_scale;
00148         result.blue *= m_scale;
00149         
00150         return result;
00151     }
00152 
00153     PixelType get_value(const unsigned int Start, const unsigned int End)
00154     {
00155         double scale = std::accumulate(m_weights.begin() + Start, m_weights.begin() + End, 0.0);
00156         if(scale)
00157             scale = 1.0 / scale;    
00158     
00159         PixelType result;
00160         
00161         weight_collection_type::const_iterator weight = m_weights.begin() + Start;
00162         for(typename value_collection_type::iterator value = m_values.begin() + Start; value != m_values.begin() + End; ++value, ++weight)
00163             {
00164                 result.red += (value->red) * (*weight);
00165                 result.green += (value->green) * (*weight);
00166                 result.blue += (value->blue) * (*weight);
00167             }
00168             
00169         result.red *= scale;
00170         result.green *= scale;
00171         result.blue *= scale;
00172         
00173         return result;
00174     }
00175 
00176 private:
00177     typedef std::vector<double> weight_collection_type;
00178     weight_collection_type m_weights;
00179     
00180     typedef std::deque<PixelType> value_collection_type;
00181     value_collection_type m_values;
00182     
00183     double m_scale;
00184 };
00185 
00187 template<typename ResourceType>
00188 class raii
00189 {
00190 public:
00191     raii(ResourceType* const Resource, void (*ReleaseMethod)(ResourceType*)) :
00192         m_resource(Resource),
00193         m_release_method(ReleaseMethod)
00194     {
00195         // Sanity checks ...
00196         assert(m_release_method);
00197     }
00198     
00199     ~raii()
00200     {
00201         if(m_resource)
00202             (*m_release_method)(m_resource);
00203     }
00204 
00205     ResourceType* get() const
00206     {
00207         return m_resource;
00208     }
00209             
00210     ResourceType* operator->() const
00211     {
00212         return m_resource;
00213     }
00214     
00215     ResourceType& operator*() const
00216     {
00217         return *m_resource;
00218     }
00219 
00220 private:
00221     ResourceType* const m_resource;
00222     void (*m_release_method)(ResourceType*);
00223 };
00224 
00225 } // namespace kino
00226 
00227 #endif // !KINO_PLUGIN_UTILITY_H

Generated on Sun Mar 11 22:11:46 2007 for Kino by  doxygen 1.4.2