diff --git a/splinterpolator.h b/splinterpolator.h
new file mode 100644
index 0000000000000000000000000000000000000000..c41efde431354301bd04721dc492b6fd8bfb741f
--- /dev/null
+++ b/splinterpolator.h
@@ -0,0 +1,201 @@
+//  
+//  splinterpolator.h
+//
+// Jesper Andersson, FMRIB Image Analysis Group
+//
+// Copyright (C) 2008 University of Oxford 
+//
+//     CCOPYRIGHT
+//
+
+#ifndef splinterpolator_h
+#define splinterpolator_h
+
+#include <vector>
+#include <string>
+#include <cmath>
+#include "newmat.h"
+#include "miscmaths/miscmaths.h"
+
+namespace SPLINTERPOLATOR {
+
+enum ExtrapolationType {Zeros, Constant, Mirror, Periodic};
+
+class SplinterpolatorException: public std::exception
+{
+private:
+  std::string m_msg;
+public:
+  SplinterpolatorException(const std::string& msg) throw(): m_msg(msg) {}
+
+  virtual const char *what() const throw() {
+    return string("FslSplines::" + m_msg).c_str();
+  }
+
+  ~SplinterpolatorException() throw() {}
+};
+
+template<class T>
+class Splinterpolator
+{
+public:
+  // Constructors
+  Splinterpolator() : _valid(false) {}
+  Splinterpolator(const T *data, const std::vector<unsigned int>& dim, unsigned int order=3, std::vector<ExtrapolationType> et(3,Zeros))
+  {
+    common_construction(data,dim,order,et);
+  }
+  Splinterpolator(const T *data, const std::vector<unsigned int>& dim, unsigned int order, ExtrapolationType et)
+  {
+    std::vector<ExtrapolationType>   ett(dim.size(),et);
+    common_construction(data,dim,order,ett);
+  }
+  // Destructor
+  ~Splinterpolator() { if(_valid) delete [] _coef; }
+
+  //
+  // Here we declare nested helper-class SplineColumn
+  //
+  class SplineColumn
+  {
+  public:
+    // Constructor
+    SplineColumn(unsigned int sz, unsigned int step) : _sz(sz), _step(step) { _col = new double[_sz]; }
+    // Destructor
+    ~SplineColumn() { delete [] _col; }
+    // Extract a column from a volume
+    Get(const T  *dp)
+    {
+      for (unsigned int i=0; i<_sz; i++, dp+=_step) _col[i] = static_cast<double>(*dp);
+    }
+    // Insert column into volume
+    Set(T *dp)
+    {
+      T   test = 1.5;
+      if (test == 1) {  // If T is not float or double
+        for (unsigned int i=0; i<_sz; i++, dp+=_step) *dp = static_cast<T>(_col[i] + 0.5);   // Round to nearest integer
+      }
+      else {
+        for (unsigned int i=0; i<_sz; i++, dp+=_step) *dp = static_cast<T>(_col[i]);
+      }
+    }
+    // Deconvolve column
+    Deconv(unsigned int order, ExtrapolationType et) {};
+
+  private:
+    unsigned int  _sz;
+    unsigned int  _step;
+    double        *_col;
+
+    SplineColumn(const SplineColumn& sc);              // Don't allow copy-construction
+    SplineColumn& operator=(const SplineColumn& sc);   // Dont allow assignment
+  };
+
+  void Set(const T *data, const std::vector<unsigned int>& dim, unsigned int order=3, std::vector<ExtrapolationType> et(3,Zeros))
+  {
+    if (_valid) delete [] _coef;
+    common_construction(data,dim,order,et);
+  }
+  
+private:
+  bool                            _valid;         // Decides if neccessary information has been set or not
+  T                               *_coef;         // Volume of spline coefficients
+  unsigned int                    _order;         // Order of splines
+  std::vector<unsigned int>       _dim;           // Dimensions of data
+  std::vector<ExtrapolationType>  _et;            // How to do extrapolation
+  //
+  // Private helper-functions
+  //
+  void common_construction(const T *data, const std::vector<unsigned int>& dim, unsigned int order, const std::vector<ExtrapolationType>& et);
+  void calc_coef(const T *data);
+  void deconv_along(unsigned int dim);
+  //
+  // Disallowed member functions
+  //
+  Splinterpolator(const Splinterpolator& s);             // Don't allow copy-construction
+  Splinterpolator& operator=(const Splinterpolator& s);  // Don't allow assignment
+};
+
+template<class T>
+void Splinterpolator<T>::common_construction(const T *data, const std::vector<unsigned int>& dim, unsigned int order, const std::vector<ExtrapolationType>& et)
+{
+  if (!dim.size()) throw SplinterpolatorException("Splinterpolator::common_construction: data has zeros dimensions");
+  if (!dim.size() > 5) throw SplinterpolatorException("Splinterpolator::common_construction: data cannot have more than 5 dimensions");
+  if (dim.size() != et.size()) throw SplinterpolatorException("Splinterpolator::common_construction: dim and et must have the same size");
+  for (unsigned int i=0; i<dim.size(); i++) if (!dim[i]) throw SplinterpolatorException("Splinterpolator::common_construction: data cannot have zeros size in any direction");
+  if (order > 7) throw SplinterpolatorException("Splinterpolator::common_construction: spline order must be lesst than 7");
+  if (!data) throw SplinterpolatorException("Splinterpolator::common_construction: zero data pointer");
+  
+  for (unsigned int ts=1, i=0; i<dim.size(); i++) ts *= dim[i];
+  _coef = new T[ts];
+  _order = order;
+  _dim.resize(5); = dim;
+  _et = et;
+
+  calc_coef(data);
+
+  _valid = true;
+}
+
+template<class T>
+void Splinterpolator<T>::calc_coef(const T *data)
+{
+  // Put the original data into _coef
+  //
+  for (unsigned int ts=1, i=0; i<dim.size(); i++) ts *= dim[i];
+  memcpy(_coef,data,ts*sizeof(T));
+
+  if (_order < 2) return;  // If nearest neighbour or linear, that's all we need 
+
+  // Loop over all non-singleton dimensions and deconvolve along them
+  //
+  std::vector<unsigned int>  tdim(dim.size()-1,0); 
+  for (unsigned int cdir=0; cdir<dim.size(); cdir++) {
+    if (dim[cdir] > 1) deconv_along(cdir)
+  }
+
+  return;
+}
+
+template<class T>
+void Splinterpolator<T>::deconv_along(unsigned int dim);
+{
+  T  *dp = _coef;
+
+  // Set up to reflect "missing" dimension
+  //
+  std::vector<unsigned int>   rdim(4,1);     // Sizes along remaining dimensions
+  std::vector<unsigned int>   rstep(4,1);    // Step-sizes (in "volume") of remaining dimensions
+  unsigned int                mdim = 1;      // Size along "missing" dimension
+  unsigned int                mstep = 1;     // Step-size along "missing" dimension
+  for (unsigned int i=0, j=0, s=1; i<5; i++) {
+    if (i == dim) {  // If it is our "missing" dimension
+      mdim = _dim(i);
+      mstep = ss;
+    }
+    else {
+      rdim[j] = _dim[i];
+      rstep[j++] = ss;
+    }
+    ss *= _dim[i];
+  }
+
+  SplineColumn<T>  col(mdim,mstep);           // Column helps us do the job
+
+  for (unsigned int l=0; l<rdim[3]; l++, dp+=rstep[3]) {
+    for (unsigned int k=0; k<rdim[2]; k++, dp+=rstep[2]) {
+      for (unsigned int j=0; j<rdim[1]; j++, dp+=rstep[1]) {
+	for (unsigned int i=0; i<rdim[0]; i++, dp+=rstep[0]) {
+	  col.Get(dp);     // Extract a column from the volume
+          col.Deconv(_order,_et[dim]);    // Deconvolve it
+          col.Set(dp);     // Put back the deconvolved column
+	}
+      }
+    }
+  }
+  return;
+}
+
+} // End namespace SPLINTERPOLATOR
+
+#endif // End #ifndef splinterpolator.h