contrib/mul/vil3d/vil3d_transform.h
Go to the documentation of this file.
00001 // This is mul/vil3d/vil3d_transform.h
00002 #ifndef vil3d_transform_h_
00003 #define vil3d_transform_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief STL algorithm like methods.
00010 // \author Tim Cootes, Ian Scott.
00011 
00012 #include <vcl_cassert.h>
00013 #include <vcl_algorithm.h>
00014 #include <vil3d/vil3d_image_view.h>
00015 
00016 
00017 
00018 
00019 
00020 
00021 //: Apply a unary operation to each pixel in src to get dest.
00022 // \param functor should take a value of type inP, and return a value of type outP
00023 template <class inP, class outP, class Op >
00024 inline void vil3d_transform(const vil3d_image_view<inP >&src, vil3d_image_view<outP >&dest, Op functor)
00025 {
00026   const unsigned ni = src.ni(), nj= src.nj(), nk= src.nk(), np = src.nplanes();
00027   dest.set_size(ni, nj, nk, np);
00028 
00029   if (src.is_contiguous() && dest.is_contiguous())
00030   {
00031     vcl_transform(src.begin(), src.end(), dest.begin(), functor);
00032   }
00033   else
00034   {
00035     for (unsigned p = 0; p < np; ++p)
00036     for (unsigned k = 0; k < nk; ++k)
00037       for (unsigned j = 0; j < nj; ++j)
00038       {
00039         const inP* src_p = &src(0,j,k,p);
00040         vcl_ptrdiff_t src_step = src.istep();
00041         outP* dest_p = &dest(0,j,k,p);
00042         vcl_ptrdiff_t dest_step = dest.istep();
00043 
00044         for (int i = ni+1; --i != 0; src_p+=src_step, dest_p+=dest_step)
00045           *dest_p = functor(*src_p);
00046       }
00047   }
00048 }
00049 
00050 //: Apply a binary function to each pixel in src and dest that modifies dest.
00051 // \param functor should take two parameters (inP src, outP &dest);
00052 template <class inP, class outP, class Op >
00053 inline void vil3d_transform2(const vil3d_image_view<inP >&src, vil3d_image_view<outP >&dest, Op functor)
00054 {
00055   const unsigned ni = src.ni(), nj= src.nj(), nk= src.nk(), np = src.nplanes();
00056   dest.set_size(ni, nj, nk, np);
00057 
00058   // Note : Could optimise special cases significantly
00059   for (unsigned p = 0; p < np; ++p)
00060    for (unsigned k = 0; k < nk; ++k)
00061     for (unsigned j = 0; j < nj; ++j)
00062       for (unsigned i = 0; i < ni; ++i)
00063          functor(src(i,j,k,p), dest(i,j,k,p));
00064 }
00065 
00066 //: Apply a binary operation to each pixel in srcA and srcB to get dest.
00067 template <class inA, class inB, class outP, class BinOp >
00068 inline void vil3d_transform(const vil3d_image_view<inA >&srcA,
00069                            const vil3d_image_view<inB >&srcB,
00070                            vil3d_image_view<outP >&dest,
00071                            BinOp functor)
00072 {
00073   assert(srcB.ni() == srcA.ni() && srcA.nj() == srcB.nj()
00074          && srcB.nk() == srcA.nk()
00075          && srcA.nplanes() == srcB.nplanes());
00076   dest.set_size(srcA.ni(), srcA.nj(), srcA.nk(), srcA.nplanes());
00077   for (unsigned p = 0; p < srcA.nplanes(); ++p)
00078    for (unsigned k = 0; k < srcA.nk(); ++k)
00079     for (unsigned j = 0; j < srcA.nj(); ++j)
00080       for (unsigned i = 0; i < srcA.ni(); ++i)
00081         dest(i,j,k,p) = functor(srcA(i,j,k,p),srcB(i,j,k,p));
00082 }
00083 
00084 //: Apply a binary operation to each pixel in srcA and srcB to get dest.
00085 // non-const dest version, assumes dest is already correct size.
00086 template <class inA, class inB, class outP, class BinOp >
00087 inline void vil3d_transform(const vil3d_image_view<inA >&srcA,
00088                            const vil3d_image_view<inB >&srcB,
00089                            const vil3d_image_view<outP >&dest,
00090                            BinOp functor)
00091 {
00092   assert(dest.ni() == srcA.ni() && srcA.nj() == dest.nj() 
00093          && srcA.nk() == dest.nk()
00094          && srcA.nplanes() == dest.nplanes());
00095   assert(srcB.ni() == srcA.ni() && srcA.nj() == srcB.nj() 
00096          && srcA.nk() == srcB.nk()
00097          && srcA.nplanes() == srcB.nplanes());
00098   vil3d_image_view<outP >& nc_dest = const_cast<vil3d_image_view<outP >&>(dest);
00099   for (unsigned p = 0; p < srcA.nplanes(); ++p)
00100    for (unsigned k = 0; k < srcA.nk(); ++k)
00101     for (unsigned j = 0; j < srcA.nj(); ++j)
00102       for (unsigned i = 0; i < srcA.ni(); ++i)
00103         nc_dest(i,j,k,p) = functor(srcA(i,j,k,p),srcB(i,j,k,p));
00104 }
00105 
00106 
00107 #endif // vil3d_transform_h_
00108