TuttleOFX  1
kernel.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef _TERRY_NUMERIC_KERNEL_HPP_
00010 #define _TERRY_NUMERIC_KERNEL_HPP_
00011 
00012 /*!
00013 /// \file
00014 /// \brief Definitions of 1D fixed-size and variable-size kernels and related operations
00015 /// \author Hailin Jin and Lubomir Bourdev \n
00016 ///         Adobe Systems Incorporated
00017 /// \date   2005-2007 \n Last updated on September 26, 2006
00018 */
00019 
00020 
00021 #include <boost/gil/gil_config.hpp>
00022 #include <boost/gil/utilities.hpp>
00023 
00024 #include <boost/array.hpp>
00025 #include <boost/mpl/bool.hpp>
00026 
00027 #include <cstddef>
00028 #include <cassert>
00029 #include <algorithm>
00030 #include <vector>
00031 #include <memory>
00032 
00033 namespace terry {
00034 namespace filter {
00035 
00036 using namespace boost::gil;
00037 
00038 namespace detail {
00039 
00040 /// \brief kernel adaptor for one-dimensional cores
00041 /// Core needs to provide size(),begin(),end(),operator[],
00042 ///                       value_type,iterator,const_iterator,reference,const_reference
00043 template <typename Core>
00044 class kernel_1d_adaptor : public Core {
00045 private:
00046     std::size_t _center;
00047 public:
00048     kernel_1d_adaptor() : _center(0) {}
00049     explicit kernel_1d_adaptor(std::size_t center_in) : _center(center_in) {assert(_center<this->size());}
00050     kernel_1d_adaptor(std::size_t size_in,std::size_t center_in) :
00051         Core(size_in), _center(center_in) {assert(_center<this->size());}
00052     kernel_1d_adaptor(const kernel_1d_adaptor& k_in) : Core(k_in), _center(k_in._center) {}
00053 
00054     kernel_1d_adaptor& operator=(const kernel_1d_adaptor& k_in) {
00055         Core::operator=(k_in);
00056         _center=k_in._center;
00057         return *this;
00058     }
00059     std::size_t left_size() const {assert((_center<this->size()) || (this->size()==0));return _center;}
00060     std::size_t right_size() const {assert((_center<this->size()) || (this->size()==0));return this->size()?this->size()-_center-1:0;}
00061           std::size_t& center()       {return _center;}
00062     const std::size_t& center() const {return _center;}
00063     void set_center( const std::size_t center ) { _center = center; }
00064 };
00065 
00066 } // namespace detail
00067 
00068 /// \brief variable-size kernel
00069 template <typename T, typename Alloc = std::allocator<T> >
00070 class kernel_1d : public detail::kernel_1d_adaptor<std::vector<T,Alloc> > {
00071     typedef detail::kernel_1d_adaptor<std::vector<T,Alloc> > parent_t;
00072 public:
00073         typedef T value_type;
00074         typedef boost::mpl::false_ is_fixed_size_t;
00075 public:
00076     kernel_1d() {}
00077     kernel_1d(std::size_t size_in,std::size_t center_in) : parent_t(size_in,center_in) {}
00078     template <typename FwdIterator>
00079     kernel_1d(FwdIterator elements, std::size_t size_in, std::size_t center_in) : parent_t(size_in,center_in) {
00080         boost::gil::detail::copy_n(elements,size_in,this->begin());
00081     }
00082     kernel_1d(const kernel_1d& k_in)                     : parent_t(k_in) {}
00083 };
00084 
00085 /// \brief static-size kernel
00086 template <typename T,std::size_t Size>
00087 class kernel_1d_fixed : public detail::kernel_1d_adaptor<boost::array<T,Size> > {
00088     typedef detail::kernel_1d_adaptor<boost::array<T,Size> > parent_t;
00089 public:
00090         typedef T value_type;
00091         typedef boost::mpl::true_ is_fixed_size_t;
00092 public:
00093     kernel_1d_fixed() {}
00094     explicit kernel_1d_fixed(std::size_t center_in) : parent_t(center_in) {}
00095     
00096     template <typename FwdIterator>
00097     explicit kernel_1d_fixed(FwdIterator elements, std::size_t center_in) : parent_t(center_in) {
00098         boost::gil::detail::copy_n(elements,Size,this->begin());
00099     }
00100     kernel_1d_fixed(const kernel_1d_fixed& k_in)    : parent_t(k_in) {}
00101 };
00102 
00103 /// \brief reverse a kernel
00104 template <typename Kernel>
00105 inline Kernel reverse_kernel(const Kernel& kernel) {
00106     Kernel result(kernel);
00107     result.center()=kernel.right_size();
00108     std::reverse(result.begin(), result.end());
00109     return result;
00110 }
00111 
00112 
00113 }
00114 }
00115 
00116 #endif