00001
00002 #ifndef vil_bilin_interp_h_
00003 #define vil_bilin_interp_h_
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <vcl_cassert.h>
00016 #include <vcl_cstddef.h>
00017 #include <vil/vil_image_view.h>
00018 #include <vil/vil_na.h>
00019
00020
00021
00022
00023 template<class T>
00024 inline double vil_bilin_interp_unsafe(double x, double y, const T* data,
00025 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00026 {
00027 int p1x=int(x);
00028 double normx = x-p1x;
00029 int p1y=int(y);
00030 double normy = y-p1y;
00031
00032 const T* pix1 = data + p1y*ystep + p1x*xstep;
00033
00034 double i1 = pix1[0 ]+(pix1[ ystep]-pix1[0 ])*normy;
00035 double i2 = pix1[xstep]+(pix1[xstep+ystep]-pix1[xstep])*normy;
00036
00037 return i1+(i2-i1)*normx;
00038 }
00039
00040
00041
00042
00043
00044
00045
00046 template<class T>
00047 inline double vil_bilin_interp_unsafe(double x, double y, const T* data,
00048 int , int ,
00049 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00050 {
00051 return vil_bilin_interp_unsafe(x, y, data, xstep, ystep);
00052 }
00053
00054
00055
00056
00057 template<class T>
00058 inline double vil_bilin_interp_raw(double x, double y, const T* data,
00059 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00060 {
00061 int p1x=int(x);
00062 double normx = x-p1x;
00063 int p1y=int(y);
00064 double normy = y-p1y;
00065
00066 const T* pix1 = data + p1y*ystep + p1x*xstep;
00067
00068
00069
00070 if (normx == 0 && normy == 0) return pix1[0];
00071 if (normx == 0) return pix1[0]+(pix1[ystep]-pix1[0])*normy;
00072 if (normy == 0) return pix1[0]+(pix1[xstep]-pix1[0])*normx;
00073
00074 double i1 = pix1[0 ]+(pix1[ ystep]-pix1[0 ])*normy;
00075 double i2 = pix1[xstep]+(pix1[xstep+ystep]-pix1[xstep])*normy;
00076
00077 return i1+(i2-i1)*normx;
00078 }
00079
00080
00081
00082
00083
00084
00085 template<class T>
00086 inline double vil_bilin_interp_raw(double x, double y, const T* data,
00087 int , int ,
00088 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00089 {
00090 return vil_bilin_interp_raw(x, y, data, xstep, ystep);
00091 }
00092
00093
00094
00095
00096
00097 template<class T>
00098 inline double vil_bilin_interp_safe(double x, double y, const T* data,
00099 int nx, int ny,
00100 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00101 {
00102 if (x<0) return 0.0;
00103 if (y<0) return 0.0;
00104 if (x>nx-1) return 0.0;
00105 if (y>ny-1) return 0.0;
00106 return vil_bilin_interp_raw(x,y,data,xstep,ystep);
00107 }
00108
00109
00110
00111
00112
00113
00114 template<class T>
00115 inline double vil_bilin_interp_safe_edgena(double x, double y, const T* data,
00116 int nx, int ny,
00117 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00118 {
00119 if (x<0 || y<0 || x>nx-1 || y>ny-1) return vil_na(double());
00120 return vil_bilin_interp_raw(x,y,data,xstep,ystep);
00121 }
00122
00123
00124
00125
00126
00127 template<class T>
00128 inline double vil_bilin_interp_safe(const vil_image_view<T> &view,
00129 double x, double y, unsigned p=0)
00130 {
00131 return vil_bilin_interp_safe(x, y, &view(0,0,p),
00132 view.ni(), view.nj(),
00133 view.istep(), view.jstep());
00134 }
00135
00136
00137
00138
00139
00140
00141 template<class T>
00142 inline double vil_bilin_interp_safe_edgena(const vil_image_view<T> &view,
00143 double x, double y, unsigned p=0)
00144 {
00145 return vil_bilin_interp_safe_edgena(x, y, &view(0,0,p),
00146 view.ni(), view.nj(),
00147 view.istep(), view.jstep());
00148 }
00149
00150
00151
00152
00153
00154
00155 template<class T>
00156 inline double vil_bilin_interp(double x, double y, const T* data,
00157 int nx, int ny,
00158 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00159 {
00160 assert (x>=0);
00161 assert (y>=0);
00162 assert (x<=nx-1);
00163 assert (y<=ny-1);
00164 return vil_bilin_interp_raw(x,y,data,xstep,ystep);
00165 }
00166
00167
00168
00169
00170
00171
00172 template<class T>
00173 inline double vil_bilin_interp(const vil_image_view<T> &view,
00174 double x, double y, unsigned p=0)
00175 {
00176 return vil_bilin_interp(x, y, &view(0,0,p),
00177 view.ni(), view.nj(),
00178 view.istep(), view.jstep());
00179 }
00180
00181
00182
00183
00184
00185
00186 template<class T>
00187 inline double vil_bilin_interp_safe_extend(double x, double y, const T* data,
00188 int nx, int ny,
00189 vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep)
00190 {
00191 if (x<0) x= 0.0;
00192 if (y<0) y= 0.0;
00193 if (x>nx-1) x=nx-1.0;
00194 if (y>ny-1) y=ny-1.0;
00195 return vil_bilin_interp_raw(x,y,data,xstep,ystep);
00196 }
00197
00198
00199
00200
00201
00202 template<class T>
00203 inline double vil_bilin_interp_safe_extend(const vil_image_view<T> &view,
00204 double x, double y, unsigned p=0)
00205 {
00206 return vil_bilin_interp_safe_extend(x, y, &view(0,0,p),
00207 view.ni(), view.nj(),
00208 view.istep(), view.jstep());
00209 }
00210
00211 #endif // vil_bilin_interp_h_