USGS

Isis 3.0 Object Programmers' Reference

Home

Interpolator.cpp
Go to the documentation of this file.
1 
24 #include <string>
25 #include "IException.h"
26 #include "Interpolator.h"
27 
28 using namespace std;
29 namespace Isis {
33  Interpolator::Interpolator() {
34  Init();
35  }
36 
44  Interpolator::Interpolator(const interpType &type) {
45  Init();
46  p_type = type;
47  }
48 
50  Interpolator::~Interpolator() {}
51 
53  void Interpolator::Init() {
54  p_type = None;
55  }
56 
72  double Interpolator::Interpolate(const double isamp, const double iline,
73  const double buf[]) {
74 
75  switch(p_type) {
76  case None: {
77  string message = "Interpolator type not set";
78  throw IException(IException::Programmer, message, _FILEINFO_);
79  break;
80  }
81  case NearestNeighborType:
82  return NearestNeighbor(isamp, iline, buf);
83  break;
84  case BiLinearType:
85  return BiLinear(isamp, iline, buf);
86  break;
87  case CubicConvolutionType:
88  return CubicConvolution(isamp, iline, buf);
89  break;
90  }
91 
92  string message = "Invalid interpolator";
93  throw IException(IException::Programmer, message, _FILEINFO_);
94  }
101  void Interpolator::SetType(const interpType &type) {
102  p_type = type;
103  }
104 
105 
117  double Interpolator::NearestNeighbor(const double isamp, const double iline,
118  const double buf[]) {
119  return buf[0];
120  }
121 
122 
134  double Interpolator::BiLinear(const double isamp, const double iline,
135  const double buf[]) {
136 
137  // Get the fractional portions of the sample and line coordinates
138  double j = int (isamp);
139  double k = int (iline);
140  double a = isamp - j;
141  double b = iline - k;
142 
143  // If any of the 4 pixels are special pixels, drop down to a nearest neighbor
144  for(int i = 0; i < 4; i++) {
145  if(Isis::IsSpecial(buf[i])) {
146  return NearestNeighbor(isamp, iline,
147  &buf[(int)(a + 0.5) + 2 * (int)(b+0.5)]);
148  break;
149  }
150  }
151 
152  // Otherwise do the bilinear
153  return (1.0 - a) * (1.0 - b) * buf[0] +
154  a * (1.0 - b) * buf[1] +
155  (1.0 - a) * b * buf[2] +
156  a * b * buf[3];
157 
158  }
159 
172  double Interpolator::CubicConvolution(const double isamp,
173  const double iline,
174  const double buf[]) {
175 
176  // If any of the 16 pixels are special pixels, drop down to a bilinear
177  for(int i = 0; i < 16; i++) {
178  if(Isis::IsSpecial(buf[i])) {
179  double tbuf[4] = {buf[5], buf[6], buf[9], buf[10]};
180  return BiLinear(isamp, iline, tbuf);
181  break;
182  }
183  }
184 
185  double j = int (isamp);
186  double k = int (iline);
187  double a = isamp - j;
188  double b = iline - k;
189 
197  return -b * (1.0 - b) * (1.0 - b) * (-a * (1.0 - a) * (1.0 - a) * buf[0] +
198  (1.0 - 2.0 * a * a + a * a * a) * buf[1] +
199  a * (1.0 + a - a * a) * buf[2] -
200  a * a * (1.0 - a) * buf[3]) +
201 
202  (1.0 - 2.0 * b * b + b * b * b) * (-a * (1.0 - a) * (1.0 - a) * buf[4] +
203  (1.0 - 2.0 * a * a + a * a * a) * buf[5] +
204  a * (1.0 + a - a * a) * buf[6] -
205  a * a * (1.0 - a) * buf[7]) +
206 
207  b * (1.0 + b - b * b) * (-a * (1.0 - a) * (1.0 - a) * buf[8] +
208  (1.0 - 2.0 * a * a + a * a * a) * buf[9] +
209  a * (1.0 + a - a * a) * buf[10] -
210  a * a * (1.0 - a) * buf[11]) +
211 
212  b * b * (b - 1.0) * (-a * (1.0 - a) * (1.0 - a) * buf[12] +
213  (1.0 - 2.0 * a * a + a * a * a) * buf[13] +
214  a * (1.0 + a - a * a) * buf[14] -
215  a * a * (1.0 - a) * buf[15]);
216 
217  }
218 
224  int Interpolator::Samples() {
225 
226  switch(p_type) {
227  case None: {
228  string message = "Interpolator type not set";
229  throw IException(IException::Programmer, message, _FILEINFO_);
230  break;
231  }
232  case NearestNeighborType:
233  return 1;
234  break;
235  case BiLinearType:
236  return 2;
237  break;
238  case CubicConvolutionType:
239  return 4;
240  break;
241  }
242 
243  string message = "Invalid interpolator";
244  throw IException(IException::Programmer, message, _FILEINFO_);
245  }
246 
252  int Interpolator::Lines() {
253 
254  switch(p_type) {
255  case None: {
256  string message = "Interpolator type not set";
257  throw IException(IException::Programmer, message, _FILEINFO_);
258  break;
259  }
260  case NearestNeighborType:
261  return 1;
262  break;
263  case BiLinearType:
264  return 2;
265  break;
266  case CubicConvolutionType:
267  return 4;
268  break;
269  }
270 
271  string message = "Invalid interpolator";
272  throw IException(IException::Programmer, message, _FILEINFO_);
273  }
274 
281  double Interpolator::HotSample() {
282 
283  switch(p_type) {
284  case None: {
285  string message = "Interpolator type not set";
286  throw IException(IException::Programmer, message, _FILEINFO_);
287  break;
288  }
289  // To get the correct pixel for NN you have to round the sample
290  case NearestNeighborType:
291  return -0.5;
292  break;
293  // To get the correct pixel for BL you have to truncate the sample
294  case BiLinearType:
295  return 0.0;
296  break;
297  // To get the correct pixel for CC you have to truncate the sample
298  case CubicConvolutionType:
299  return 1.0;
300  break;
301  }
302 
303  string message = "Invalid interpolator";
304  throw IException(IException::Programmer, message, _FILEINFO_);
305  }
306 
313  double Interpolator::HotLine() {
314 
315  switch(p_type) {
316  case None: {
317  string message = "Interpolator type not set";
318  throw IException(IException::Programmer, message, _FILEINFO_);
319  break;
320  }
321  // To get the correct pixel for NN you have to round the line
322  case NearestNeighborType:
323  return -0.5;
324  break;
325  // To get the correct pixel for BL you have to truncate the line
326  case BiLinearType:
327  return 0.0;
328  break;
329  // To get the correct pixel for CC you have to truncate the line
330  case CubicConvolutionType:
331  return 1.0;
332  break;
333  }
334 
335  string message = "Invalid interpolator";
336  throw IException(IException::Programmer, message, _FILEINFO_);
337  }
338 }