OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimResampler.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts
6 //
7 //
8 // Description:
9 //
10 // Contains class definition for ossimResampler.
11 //
12 //*******************************************************************
13 // $Id: ossimResampler.cpp 20204 2011-11-04 15:12:28Z dburken $
14 
15 
16 #include <iostream>
17 using namespace std;
19 #include <ossim/base/ossimDpt.h>
20 #include <ossim/base/ossimDpt3d.h>
21 #include <ossim/base/ossimCommon.h>
29 
31 
32 
33 static const char* RESAMPLER_CONVOLUTION_TYPE_KW = "convolution_type";
34 static const char* RESAMPLER_SCALE_X_KW = "scale_x";
35 static const char* RESAMPLER_SCALE_Y_KW = "scale_y";
36 static const char* RESAMPLER_CUBIC_PARAMETER_KW = "cubic_parameter";
37 
39  :ossimConnectableObject(NULL,0,0,true, false),
40  theOutputToInputRatio(1,1),
41  theResamplerType(ossimResampler_NONE),
42  theTableWidthX(0),
43  theTableWidthY(0),
44  theTableHeight(0),
45  theKernelWidth(0),
46  theKernelHeight(0),
47  theWeightTableX(NULL),
48  theWeightTableY(NULL),
49  theCubicAdjustableParameter(-.5)
50 {
51 }
52 
54 {
56 }
57 
59  ossimImageData* output)
60 {
61  if(!input||
62  !output ||
63  !input->getBuf() ||
64  !output->getBuf())
65  {
66  return;
67  }
68 
70  {
71  ossimScalarType scalarType = input->getScalarType();
72  switch(scalarType)
73  {
74  case OSSIM_UINT8:
75  {
76  resampleTile(ossim_uint8(0), // dummy template variable
77  input,
78  output);
79  break;
80  }
81  case OSSIM_UINT16:
82  case OSSIM_USHORT11:
83  case OSSIM_USHORT12:
84  case OSSIM_USHORT13:
85  case OSSIM_USHORT14:
86  case OSSIM_USHORT15:
87  {
88  resampleTile(ossim_uint16(0), // dummy template variable
89  input,
90  output);
91  break;
92  }
93  case OSSIM_SSHORT16:
94  {
95  resampleTile(ossim_sint16(0), // dummy template variable
96  input,
97  output);
98  break;
99  }
100  case OSSIM_UINT32:
101  {
102  resampleTile(ossim_uint32(0), // dummy template variable
103  input,
104  output);
105  break;
106  }
107  case OSSIM_FLOAT32:
109  {
110  resampleTile(ossim_float32(0.0), // dummy template variable
111  input,
112  output);
113  break;
114  }
115  case OSSIM_FLOAT64:
117  {
118  resampleTile(ossim_float64(0.0), // dummy template variable
119  input,
120  output);
121  break;
122  }
123  default:
124  {
126  << "ossimResampler::resample error: unknown scalar type: "
127  << scalarType
128  << endl;
129 
130  }
131  }
132  }
133  // convolve the input and copy to output.
134 }
135 
137  ossimImageData* output,
138  const ossimDpt& ul,
139  const ossimDpt& ur,
140  const ossimDpt& deltaUl,
141  const ossimDpt& deltaUr,
142  const ossimDpt& length)
143 {
144  resample(input,
145  output,
146  output->getImageRectangle(),
147  ul,
148  ur,
149  deltaUl,
150  deltaUr,
151  length);
152 }
153 
155  ossimImageData* output,
156  const ossimIrect& outputSubRect,
157  const ossimDpt& ul,
158  const ossimDpt& ur,
159  const ossimDpt& deltaUl,
160  const ossimDpt& deltaUr,
161  const ossimDpt& length)
162 {
163  if(!input||
164  !output ||
165  !input->getBuf() ||
166  !output->getBuf())
167  {
168  return;
169  }
170 
172  {
173  ossimScalarType scalarType = input->getScalarType();
174  switch(scalarType)
175  {
176  case OSSIM_UINT8:
177  {
178  resampleTile(ossim_uint8(0), // dummy template variable
179  input,
180  output,
181  outputSubRect,
182  ul,
183  ur,
184  deltaUl,
185  deltaUr,
186  length);
187  break;
188  }
189  case OSSIM_UINT16:
190  case OSSIM_USHORT11:
191  case OSSIM_USHORT12:
192  case OSSIM_USHORT13:
193  case OSSIM_USHORT14:
194  case OSSIM_USHORT15:
195  {
196  resampleTile(ossim_uint16(0), // dummy template variable
197  input,
198  output,
199  outputSubRect,
200  ul,
201  ur,
202  deltaUl,
203  deltaUr,
204  length);
205  break;
206  }
207  case OSSIM_SINT16:
208  {
209  resampleTile(ossim_sint16(0), // dummy template variable
210  input,
211  output,
212  outputSubRect,
213  ul,
214  ur,
215  deltaUl,
216  deltaUr,
217  length);
218  break;
219  }
220  case OSSIM_UINT32:
221  {
222  resampleTile(ossim_uint32(0), // dummy template variable
223  input,
224  output,
225  outputSubRect,
226  ul,
227  ur,
228  deltaUl,
229  deltaUr,
230  length);
231  break;
232  }
233  case OSSIM_FLOAT32:
235  {
236  resampleTile(ossim_float32(0.0), // dummy template variable
237  input,
238  output,
239  outputSubRect,
240  ul,
241  ur,
242  deltaUl,
243  deltaUr,
244  length);
245  break;
246  }
247  case OSSIM_FLOAT64:
249  {
250  resampleTile(ossim_float64(0.0), // dummy template variable
251  input,
252  output,
253  outputSubRect,
254  ul,
255  ur,
256  deltaUl,
257  deltaUr,
258  length);
259  break;
260  }
261  default:
262  {
264  << "ossimResampler::resample error: unknown scalar type: "
265  << scalarType
266  << endl;
267  }
268  }
269  }
270 
271 }
272 
274  ossimImageData* output,
275  const ossimIrect& outputSubRect,
276  const ossimDpt& ul,
277  const ossimDpt& ur,
278  const ossimDpt& deltaUl,
279  const ossimDpt& deltaUr,
280  const ossimDpt& length)
281 {
282  if(!input||
283  !output ||
284  !input->getBuf() ||
285  !output->getBuf())
286  {
287  return;
288  }
289 
290  ossimScalarType scalarType = input->getScalarType();
291  switch(scalarType)
292  {
293  case OSSIM_UINT8:
294  {
295  resampleTileNearestNeighbor(ossim_uint8(0),// dummy template variable
296  input,
297  output,
298  outputSubRect,
299  ul,
300  ur,
301  deltaUl,
302  deltaUr,
303  length);
304  break;
305  }
306  case OSSIM_UINT16:
307  case OSSIM_USHORT11:
308  case OSSIM_USHORT12:
309  case OSSIM_USHORT13:
310  case OSSIM_USHORT14:
311  case OSSIM_USHORT15:
312  {
313  resampleTileNearestNeighbor(ossim_uint16(0),// dummy template variable
314  input,
315  output,
316  outputSubRect,
317  ul,
318  ur,
319  deltaUl,
320  deltaUr,
321  length);
322  break;
323  }
324  case OSSIM_SINT16:
325  {
326  resampleTileNearestNeighbor(ossim_sint16(0),// dummy template variable
327  input,
328  output,
329  outputSubRect,
330  ul,
331  ur,
332  deltaUl,
333  deltaUr,
334  length);
335  break;
336  }
337  case OSSIM_UINT32:
338  {
339  resampleTileNearestNeighbor(ossim_uint32(0),// dummy template variable
340  input,
341  output,
342  outputSubRect,
343  ul,
344  ur,
345  deltaUl,
346  deltaUr,
347  length);
348  break;
349  }
350  case OSSIM_FLOAT32:
352  {
354  input,
355  output,
356  outputSubRect,
357  ul,
358  ur,
359  deltaUl,
360  deltaUr,
361  length);
362  break;
363  }
364  case OSSIM_FLOAT64:
366  {
368  input,
369  output,
370  outputSubRect,
371  ul,
372  ur,
373  deltaUl,
374  deltaUr,
375  length);
376  break;
377  }
378  default:
379  {
381  << "ossimResampler::resample error: unknown scalar type: "
382  << scalarType
383  << endl;
384  }
385  }
386 }
387 
389  ossimImageData* output,
390  const ossimDpt& ul,
391  const ossimDpt& ur,
392  const ossimDpt& deltaUl,
393  const ossimDpt& deltaUr,
394  const ossimDpt& length)
395 {
397  output,
398  output->getImageRectangle(),
399  ul,
400  ur,
401  deltaUl,
402  deltaUr,
403  length);
404 }
405 
406 
407 template <class T>
409  ossimImageData* input,
410  ossimImageData* output)
411 {
412  switch(input->getDataObjectStatus())
413  {
414  case OSSIM_FULL:
415  {
416  resampleFullTile((T)0, input, output);
417  break;
418  }
419  case OSSIM_PARTIAL:
420  {
421  resamplePartialTile((T)0, input, output);
422  break;
423  }
424  default:
425  {
426  break;
427  }
428  }
429 }
430 
431 template <class T>
433  ossimImageData* input,
434  ossimImageData* output)
435 {
436  ossim_int32 maxInputSize = std::max(input->getWidth(), input->getHeight());
437  ossim_int32 maxOutputSize = std::max(output->getWidth(), output->getHeight());
438  ossim_int32 k;
439  double *h = new double[maxInputSize];
440  int *Lx = new int[maxOutputSize];
441  int *Ly = new int[maxOutputSize];
442  ossim_int32 out_height = output->getHeight();
443  ossim_int32 out_width = output->getWidth();
444  ossim_int32 in_width = input->getWidth();
445  ossim_int32 in_height = input->getHeight();
446  ossim_int32 j;
447  ossim_int32 l;
448 
449  ossimIpt origin=output->getOrigin();
450  ossimIpt scaledOriginShift(input->getOrigin()*-1);
451 
452  ossim_int32 evenKernelW = (ossim_int32)(!(theKernelWidth%2));
453  ossim_int32 evenKernelH = (ossim_int32)(!(theKernelHeight%2));
454  ossim_int32 kernelHorizontalShift = (ossim_int32)(-theKernelWidth/2.0+evenKernelW);
455  ossim_int32 kernelVerticalShift = (ossim_int32)(-theKernelHeight/2.0+evenKernelH);
456 
457  for (k = 0; k < maxOutputSize; ++k)
458  {
459  Lx[k] = (ossim_int32)(scaledOriginShift.x+((k+origin.x)/
461  }
462  for (k = 0; k < maxOutputSize; ++k)
463  {
464  Ly[k] = (ossim_int32)(scaledOriginShift.y+((k+origin.y)/
466  }
467  for(ossim_int32 band = 0; band < (ossim_int32)input->getNumberOfBands();++band)
468  {
469  const T* inputBuf = static_cast<T*>(input->getBuf(band));
470  T* outputBuf = static_cast<T*>(output->getBuf(band));
471  T minPix = static_cast<T>(input->getMinPix(band));
472  T maxPix = static_cast<T>(input->getMaxPix(band));
473  T np = static_cast<T>(input->getNullPix(band));
474 
475  for (k = 0; k < out_height; ++k)
476  {
477  ossim_int32 indexMod = (ossim_int32)fmod((k+origin.y), theOutputToInputRatio.y);
478  if(indexMod >= theTableWidthY) indexMod = theTableWidthY - 1;
479  if(indexMod <0) indexMod = 0;
480  for (j = 0; j < in_width; ++j)
481  {
482  h[j] = 0.0;
483  ossim_int32 count = 0;
484  double lastValue = ossim::nan();
485  for (l = 0; l < theKernelHeight; ++l)
486  {
487  ossim_int32 index = Ly[k] + l + kernelVerticalShift;
488  if ((index >= 0) && (index < in_height))
489  {
490  ossim_int32 offset = index*in_width +j;
491  if(!input->isNull(offset))
492  {
493  lastValue = (double)inputBuf[offset];
494  h[j] += lastValue *
495  theWeightTableY[theKernelHeight - l-1][indexMod];
496  ++count;
497  }
498  // I think instead of skipping to next value I'll just assume 0
499 
500  // this was code to skip to next non-null value and use it
501  //
502 // else
503 // {
504 // for(ossim_int32 templ = l; templ < theKernelHeight; ++templ)
505 // {
506 // index = Ly[k] + templ + kernelVerticalShift;
507 // offset = index*in_width +j;
508 // if(!input->isNull(offset))
509 // {
510 // lastValue = (double)inputBuf[offset];
511 // break;
512 // }
513 // }
514 // if(ossim::isnan(lastValue) == false)
515 // {
516 // h[j] += lastValue *
517 // theWeightTableY[theKernelHeight - l-1][indexMod];
518 
519 // ++count;
520 // }
521 // else
522 // {
523 // break;
524 // }
525 // }
526  }
527  }
528  if(!count)
529  {
530  h[j] = ossim::nan();
531  }
532  }
533  for (ossim_int32 m = 0; m < out_width; ++m)
534  {
535  double x = 0.0;
536  ossim_int32 indexMod = (ossim_int32)fmod((m+origin.x), theOutputToInputRatio.x);
537  if(indexMod >= theTableWidthX) indexMod = theTableWidthX-1;
538  if(indexMod <0) indexMod = 0;
539 
540  if(input->isNull(ossimIpt(Lx[m]-scaledOriginShift.x, Ly[k]-scaledOriginShift.y)))
541  {
542  outputBuf[k*out_width +m] = np;
543  }
544  else
545  {
546  for (l = 0; l < theKernelWidth; ++l)
547  {
548  ossim_int32 index = Lx[m] + l + kernelHorizontalShift;
549  if ((index >= 0) && (index < in_width))
550  {
551  if(ossim::isnan(h[index]) == false)
552  {
553  x += h[index] * theWeightTableX[theKernelWidth - l-1][indexMod];
554  }
555 
556  // I am commenting out the code that searches for the next
557  // non null value with the kernel range. This will have the
558  // same effect as multiplying by 0.0 for the NULL value.
559  //
560 // else
561 // {
562 // for(ossim_int32 templ = l; templ < l; ++templ)
563 // {
564 // ossim_int32 index = Lx[m] + templ + kernelHorizontalShift;
565 // if(ossim::isnan(h[index]) == false))
566 // {
567 // lastValue = h[index];
568 // break;
569 // }
570 // }
571 // if(ossim::isnan(lastValue) == false)
572 // {
573 // x += lastValue * theWeightTableX[theKernelWidth - l-1][indexMod];
574 // }
575 // }
576  }
577  }
578  if (x < minPix)
579  {
580  outputBuf[k*out_width +m] = static_cast<T>(minPix);
581  }
582  else if (x > maxPix)
583  {
584  outputBuf[k*out_width +m] = static_cast<T>(maxPix);
585  }
586  else
587  {
588  outputBuf[k*out_width +m] = static_cast<T>(x);
589  }
590  }
591  }
592  }
593  }
594 
595  delete [] h;
596  delete [] Lx;
597  delete [] Ly;
598 }
599 
600 template <class T>
602  ossimImageData* input,
603  ossimImageData* output)
604 {
605  ossim_int32 maxInputSize = std::max(input->getWidth(), input->getHeight());
606  ossim_int32 maxOutputSize = std::max(output->getWidth(), output->getHeight());
607  ossim_int32 k;
608  double *h = new double[maxInputSize];
609  ossim_int32 *Lx = new ossim_int32[maxOutputSize];
610  ossim_int32 *Ly = new ossim_int32[maxOutputSize];
611  ossim_int32 out_height = output->getHeight();
612  ossim_int32 out_width = output->getWidth();
613  ossim_int32 in_width = input->getWidth();
614  ossim_int32 in_height = input->getHeight();
615  ossim_int32 j;
616  ossim_int32 l;
617 
618  ossimIpt origin=output->getOrigin();
619  ossimIpt scaledOriginShift(input->getOrigin()*-1);
620 
621  ossim_int32 evenKernelW = (ossim_int32)(!(theKernelWidth%2));
622  ossim_int32 evenKernelH = (ossim_int32)(!(theKernelHeight%2));
623  ossim_int32 kernelHorizontalShift = (ossim_int32)(-theKernelWidth/2.0+evenKernelW);
624  ossim_int32 kernelVerticalShift = (ossim_int32)(-theKernelHeight/2.0+evenKernelH);
625 
626  for (k = 0; k < maxOutputSize; ++k)
627  {
628  Lx[k] = (ossim_int32)(scaledOriginShift.x+((k+origin.x)/
630  }
631  for (k = 0; k < maxOutputSize; ++k)
632  {
633  Ly[k] = (ossim_int32)(scaledOriginShift.y+((k+origin.y)/
635  }
636  for(ossim_int32 band = 0; band < (ossim_int32)input->getNumberOfBands();++band)
637  {
638  const T* inputBuf = (const T*)(input->getBuf(band));
639  T* outputBuf = (T*)(output->getBuf(band));
640  double minPix = static_cast<T>(input->getMinPix()[band]);
641  double maxPix = static_cast<T>(input->getMaxPix()[band]);
642 
643  for (k = 0; k < out_height; ++k)
644  {
645  int indexMod = (int)fmod((k+origin.y), theOutputToInputRatio.y);
646  if(indexMod >= theTableWidthY) indexMod = theTableWidthY - 1;
647  if(indexMod <0) indexMod = 0;
648  for (j = 0; j < in_width; ++j)
649  {
650  h[j] = 0.0;
651  for (l = 0; l < theKernelHeight; ++l)
652  {
653  ossim_int32 index = Ly[k] + l + kernelVerticalShift;
654  if ((index >= 0) && (index < in_height))
655  {
656  h[j] += ((double)inputBuf[index*in_width +j]) *
657  theWeightTableY[theKernelHeight - l-1][indexMod];
658  }
659  }
660  }
661  for (ossim_int32 m = 0; m < out_width; ++m)
662  {
663  double x = 0.0;
664  int indexMod = (int)fmod((m+origin.x), theOutputToInputRatio.x);
665  if(indexMod >= theTableWidthX) indexMod = theTableWidthX-1;
666  if(indexMod <0) indexMod = 0;
667 
668  for (l = 0; l < theKernelWidth; ++l)
669  {
670  ossim_int32 index = Lx[m] + l + kernelHorizontalShift;
671  if ((index >= 0) && (index < in_width))
672  {
673 
674  x += h[index] * theWeightTableX[theKernelWidth - l-1][indexMod];
675  }
676  }
677  if (x < minPix)
678  {
679  outputBuf[k*out_width +m] = static_cast<T>(minPix);
680  }
681  else if (x > maxPix)
682  {
683  outputBuf[k*out_width +m] = static_cast<T>(maxPix);
684  }
685  else
686  {
687  outputBuf[k*out_width +m] = static_cast<T>(x);
688  }
689  }
690  }
691  }
692 
693  delete [] h;
694  delete [] Lx;
695  delete [] Ly;
696 }
697 
698 
699 
700 template <class T>
702  ossimImageData* input,
703  ossimImageData* output,
704  const ossimIrect& outputSubRect,
705  const ossimDpt& inputUl,
706  const ossimDpt& inputUr,
707  const ossimDpt& deltaUl,
708  const ossimDpt& deltaUr,
709  const ossimDpt& outLength)
710 {
711  ossimRefPtr<ossimImageData> dupIn = input;
712  ossimDpt origin = input->getOrigin();
713  ossimDpt newInputUl = inputUl;
714  ossimDpt newInputUr = inputUr;
715  ossimDpt newDeltaUl = deltaUl;
716  ossimDpt newDeltaUr = deltaUr;
717 
719  {
720  newInputUl = ossimDpt(inputUl.x * theOutputToInputRatio.x,
721  inputUl.y * theOutputToInputRatio.y);
722  newInputUr = ossimDpt(inputUr.x * theOutputToInputRatio.x,
723  inputUr.y * theOutputToInputRatio.y);
724  newDeltaUl = ossimDpt(deltaUl.x * theOutputToInputRatio.x,
725  deltaUl.y * theOutputToInputRatio.y);
726  newDeltaUr = ossimDpt(deltaUr.x * theOutputToInputRatio.x,
727  deltaUr.y * theOutputToInputRatio.y);
728 
729  ossimDpt newLl = newInputUl + newDeltaUl*outLength.y;
730  ossimDpt newLr = newInputUr + newDeltaUr*outLength.y;
731 
732  ossimDrect newBoundingRect(newInputUl,
733  newInputUr,
734  newLl,
735  newLr);
736 
737 
738  newBoundingRect = ossimDrect(newBoundingRect.ul() - ossimDpt(theKernelWidth, theKernelHeight),
739  newBoundingRect.lr() + ossimDpt(theKernelWidth, theKernelHeight));
740  ossimIrect roundedRect = newBoundingRect;
741  origin = roundedRect.ul();
742 
743  dupIn = new ossimImageData(NULL,
744  input->getScalarType(),
745  input->getNumberOfBands(),
746  roundedRect.width(),
747  roundedRect.height());
748  dupIn->setOrigin(roundedRect.ul());
749  dupIn->initialize();
750  resampleTile(static_cast<T>(0), input, dupIn.get());
751  }
752  long inWidth = dupIn->getWidth();
753  long inHeight = dupIn->getHeight();
754  double stepSizeWidth = 1.0/outLength.x;
755  double stepSizeHeight = 1.0/outLength.y;
756  ossimIrect rect = dupIn->getImageRectangle();
757 
758  ossimDpt startSave(newInputUl.x - rect.ul().x,
759  newInputUl.y - rect.ul().y );
760  ossimDpt endSave(newInputUr.x - rect.ul().x,
761  newInputUr.y - rect.ul().y);
762 
763  ossimIrect outputRect = output->getImageRectangle();
764  ossimIpt subRectUl = outputSubRect.ul();
765  long subRectH = outputSubRect.height();
766  long subRectW = outputSubRect.width();
767 
768  ossimIpt outputRectUl = outputRect.ul();
769  long outputRectW = outputRect.width();
770  long resultOffset = (subRectUl.y - outputRectUl.y)*outputRectW + (subRectUl.x - outputRectUl.x);
771 
772  for(ossim_uint32 band = 0; band < input->getNumberOfBands(); ++band)
773  {
774  T* resultBuf = static_cast<T*>(output->getBuf(band))+resultOffset;
775  const T *sourceBuf = static_cast<T*>(dupIn->getBuf(band));
776  ossimDpt start = startSave;
777  ossimDpt end = endSave;
778  T np = (T)output->getNullPix(band);
779 
780  for(long y = 0; y < subRectH; ++y)
781  {
782  double deltaX = (end.x - start.x)*stepSizeWidth;
783  double deltaY = (end.y - start.y)*stepSizeHeight;
784  ossimDpt pointXY = start;
785 
786  for(long x = 0; x < subRectW; ++x)
787  {
788  int xPixel = pointXY.x<0?(int)floor(pointXY.x):(int)pointXY.x;
789  int yPixel = pointXY.y<0?(int)floor(pointXY.y):(int)pointXY.y;
790 
791 
792  if( (xPixel >=0) && (xPixel < inWidth) &&
793  (yPixel >=0) && (yPixel < inHeight))
794  {
795  resultBuf[x] = sourceBuf[yPixel*inWidth + xPixel];
796  }
797  else
798  {
799  resultBuf[x] = np;
800  }
801 
802  pointXY.y += deltaY;
803  pointXY.x += deltaX;
804  }
805  resultBuf += outputRectW;
806 
807  start.x += newDeltaUl.x;
808  start.y += newDeltaUl.y;
809  end.x += newDeltaUr.x;
810  end.y += newDeltaUr.y;
811  }
812  }
813  dupIn = 0;
814 }
815 
816 template <class T>
817 void ossimResampler::resampleTileNearestNeighbor(T, // dummy template variable
818  ossimImageData* input,
819  ossimImageData* output,
820  const ossimDpt& ul,
821  const ossimDpt& ur,
822  const ossimDpt& deltaUl,
823  const ossimDpt& deltaUr,
824  const ossimDpt& length)
825 {
827  input,
828  output,
829  output->getImageRectangle(),
830  ul,
831  ur,
832  deltaUl,
833  deltaUr,
834  length);
835 }
836 
837 template <class T>
838 void ossimResampler::resampleTileNearestNeighbor(T, // dummy template variable
839  ossimImageData* input,
840  ossimImageData* output,
841  const ossimIrect& outputSubRect,
842  const ossimDpt& ul,
843  const ossimDpt& ur,
844  const ossimDpt& deltaUl,
845  const ossimDpt& deltaUr,
846  const ossimDpt& length)
847 {
848  long inWidth = input->getWidth();
849  long inHeight = input->getHeight();
850  double stepSizeWidth = 1.0/length.x;
851  double stepSizeHeight = 1.0/length.y;
852  ossimIrect rect = input->getImageRectangle();
853 
854  ossimDpt startSave(ul.x - rect.ul().x,
855  ul.y - rect.ul().y );
856 
857  ossimDpt endSave(ur.x - rect.ul().x,
858  ur.y - rect.ul().y);
859 
860  ossimIrect outputRect = output->getImageRectangle();
861  ossimIpt subRectUl = outputSubRect.ul();
862 // ossimIpt subRectUl((int)outputSubRect.ul().x,
863 // (int)outputSubRect.ul().y);
864  long subRectH = outputSubRect.height();
865  long subRectW = outputSubRect.width();
866 
867  ossimIpt outputRectUl = outputRect.ul();
868  long outputRectW = outputRect.width();
869 
870  long resultOffset = (subRectUl.y - outputRectUl.y)*outputRectW + (subRectUl.x - outputRectUl.x);
871  for(ossim_uint32 band = 0; band < input->getNumberOfBands(); ++band)
872  {
873  T* resultBuf = static_cast<T*>(output->getBuf(band))+resultOffset;
874  const T *sourceBuf = static_cast<T*>(input->getBuf(band));
875  ossimDpt start = startSave;
876  ossimDpt end = endSave;
877  T inNp = (T)input->getNullPix(band);
878  T outNp = (T)output->getNullPix(band);
879 
880  for(long y = 0; y < subRectH; ++y)
881  {
882  double deltaX = (end.x - start.x)*stepSizeWidth;
883  double deltaY = (end.y - start.y)*stepSizeHeight;
884  ossimDpt pointXY = start;
885 
886  for(long x = 0; x < subRectW; ++x)
887  {
888  int xPixel = pointXY.x<0?(int)floor(pointXY.x):(int)pointXY.x;
889  int yPixel = pointXY.y<0?(int)floor(pointXY.y):(int)pointXY.y;
890 
891 
892  if( (xPixel >=0) && (xPixel < inWidth) &&
893  (yPixel >=0) && (yPixel < inHeight))
894  {
895  T value = sourceBuf[yPixel*inWidth + xPixel];
896 
897  if(value != inNp)
898  {
899  resultBuf[x] = value;
900  }
901  else
902  {
903  resultBuf[x] = outNp;
904  }
905  }
906  else
907  {
908  resultBuf[x] = outNp;
909  }
910 
911  pointXY.y += deltaY;
912  pointXY.x += deltaX;
913  }
914  resultBuf += outputRectW;
915 
916  start.x += deltaUl.x;
917  start.y += deltaUl.y;
918  end.x += deltaUr.x;
919  end.y += deltaUr.y;
920  }
921  }
922 }
923 
925 {
926  return theKernelWidth;
927 }
928 
930 {
931  return theKernelHeight;
932 }
933 
935 {
936  if(theWeightTableX)
937  {
938  for(ossim_int32 index = 0; index < theTableHeight; ++index)
939  {
940  delete [] theWeightTableX[index];
941  }
942  delete [] theWeightTableX;
943 
944  theWeightTableX = NULL;
945  }
946  if(theWeightTableY)
947  {
948  for(ossim_int32 index = 0; index < theTableHeight; ++index)
949  {
950  delete [] theWeightTableY[index];
951  }
952  delete [] theWeightTableY;
953 
954  theWeightTableY = NULL;
955  }
956 }
957 
958 void ossimResampler::allocateWeightTable()//uint32 outWidth)
959 {
960  if(theWeightTableX||
962  {
964  }
965 
966  switch(theResamplerType)
967  {
969  {
970  theTableHeight = 4;
971  break;
972  }
974  {
975  theTableHeight = 2;
976  break;
977  }
979  {
980  theTableHeight = 1;
981  break;
982  }
983  case ossimResampler_NONE:
984  {
986  theTableHeight = 1;
987  break;
988  }
989  }
990  theTableWidthX = (ossim_int32)ossim::round<int>(theOutputToInputRatio.x);
991  theTableWidthY = (ossim_int32)ossim::round<int>(theOutputToInputRatio.y);
993  {
994  theWeightTableX = new double*[theTableHeight];
995 
996  for(ossim_int32 index = 0; index < theTableHeight; ++index)
997  {
998  theWeightTableX[index] = new double[theTableWidthX];
999  }
1000  }
1002  {
1003  theWeightTableY = new double*[theTableHeight];
1004 
1005  for(ossim_int32 index = 0; index < theTableHeight; ++index)
1006  {
1007  theWeightTableY[index] = new double[theTableWidthY];
1008  }
1009  }
1010 }
1011 
1013 {
1014  if(theWeightTableX&&
1016  {
1017 // ossim_int32 d = theOutputToInputRatio.theDen;
1018 // ossim_int32 n = theOutputToInputRatio.theNum;
1019  ossim_int32 i = 0;
1020 
1021  double x = 0.0;
1022 
1023  switch(theResamplerType)
1024  {
1025  case ossimResampler_NONE:
1026  {
1028  for (i = 0; i < theTableWidthY; ++i)
1029  {
1030  theWeightTableY[0][i] = 1;
1031  }
1032  for (i = 0; i < theTableWidthX; ++i)
1033  {
1034  theWeightTableX[0][i] = 1;
1035  }
1036  break;
1037  }
1039  {
1040  for (i = 0; i < theTableWidthY; ++i)
1041  {
1042  theWeightTableY[0][i] = 1;
1043  }
1044  for (i = 0; i < theTableWidthX; ++i)
1045  {
1046  theWeightTableX[0][i] = 1;
1047  }
1048  break;
1049  }
1051  {
1052  for (i = 0; i < theTableWidthX; ++i)
1053  {
1054  x = (double)i/(double)(theTableWidthX);
1055  theWeightTableX[0][i] = x;
1056  theWeightTableX[1][i] = 1-x;
1057  }
1058  for (i = 0; i < theTableWidthY; ++i)
1059  {
1060  x = (double)i/(double)(theTableWidthY);
1061  theWeightTableY[0][i] = x;
1062  theWeightTableY[1][i] = 1-x;
1063  }
1064  break;
1065  }
1067  {
1068  for (i = 0; i < theTableWidthX; ++i)
1069  {
1070  x = (double)i/(double)(theTableWidthX);
1071  theWeightTableX[0][i] = getCubicC0(x);
1072  theWeightTableX[1][i] = getCubicC1(x);
1073  theWeightTableX[2][i] = getCubicC2(x);
1074  theWeightTableX[3][i] = getCubicC3(x);
1075  }
1076  for (i = 0; i < theTableWidthY; ++i)
1077  {
1078  x = (double)i/(double)(theTableWidthY);
1079  theWeightTableY[0][i] = getCubicC0(x);
1080  theWeightTableY[1][i] = getCubicC1(x);
1081  theWeightTableY[2][i] = getCubicC2(x);
1082  theWeightTableY[3][i] = getCubicC3(x);
1083  }
1084  break;
1085  }
1086  }
1087  }
1088 }
1089 
1091 {
1092  if(theResamplerType != type)
1093  {
1094  theResamplerType = type;
1095 
1096  switch(theResamplerType)
1097  {
1098  case ossimResampler_NONE:
1099  {
1101  theKernelWidth = 1;
1102  theKernelHeight = 1;
1103 
1104  break;
1105  }
1107  {
1108  theKernelWidth = 1;
1109  theKernelHeight = 1;
1110 
1111  break;
1112  }
1114  {
1115  theKernelWidth = 2;
1116  theKernelHeight = 2;
1117 
1118  break;
1119  }
1121  {
1122  theKernelWidth = 4;
1123  theKernelHeight = 4;
1124 
1125  break;
1126  }
1127  }
1128 
1131  }
1132 }
1133 
1134 void ossimResampler::setRatio(double outputToInputRatio)
1135 {
1136  // make it square
1137  setRatio(ossimDpt(outputToInputRatio, outputToInputRatio));
1138 }
1139 
1140 void ossimResampler::setRatio(const ossimDpt& outputToInputRatio)
1141 {
1142  // make it square
1143  theOutputToInputRatio.x = (outputToInputRatio.x);
1144  theOutputToInputRatio.y = (outputToInputRatio.y);
1145 
1146  if((theTableWidthX != ossim::round<int>(outputToInputRatio.x))||
1147  (theTableWidthY != ossim::round<int>(outputToInputRatio.y)))
1148  {
1151  }
1152 }
1153 
1154 double ossimResampler::getCubicC0(double t)const
1155 {
1156  return ((-theCubicAdjustableParameter * t * t * t) +
1157  (theCubicAdjustableParameter * t * t));
1158 }
1159 
1160 double ossimResampler::getCubicC1(double t)const
1161 {
1162  return (-(theCubicAdjustableParameter + 2.0) * t * t * t +
1163  (2.0 * theCubicAdjustableParameter + 3.0) * t * t -
1165 }
1166 
1167 double ossimResampler::getCubicC2(double t)const
1168 {
1169  return ((theCubicAdjustableParameter + 2.0) * t * t * t -
1170  (theCubicAdjustableParameter + 3.0) * t * t + 1.0);
1171 }
1172 
1173 double ossimResampler::getCubicC3(double t)const
1174 {
1175  return ((theCubicAdjustableParameter * t * t * t) -
1176  (2.0f * theCubicAdjustableParameter * t * t) +
1178 }
1179 
1181  const char* prefix)
1182 {
1183  const char* resamplerType = kwl.find(prefix, RESAMPLER_CONVOLUTION_TYPE_KW);
1184  const char* scaleX = kwl.find(prefix, RESAMPLER_SCALE_X_KW);
1185  const char* scaleY = kwl.find(prefix, RESAMPLER_SCALE_Y_KW);
1186  const char* cubicParameter= kwl.find(prefix, RESAMPLER_CUBIC_PARAMETER_KW);
1187 
1188  if(cubicParameter)
1189  {
1190  theCubicAdjustableParameter = ossimString(cubicParameter).toDouble();
1193  }
1194  else
1195  {
1197  }
1198  if(resamplerType)
1199  {
1200  ossimString test =ossimString(resamplerType).upcase().trim();
1201 
1202  if( test == "BICUBIC")
1203  {
1205  }
1206  else if( test == "BILINEAR")
1207  {
1209  }
1210  else
1211  {
1213  }
1214  }
1215  if(scaleX&&scaleY)
1216  {
1217  setRatio(ossimDpt(ossimString(scaleX).toDouble(),
1218  ossimString(scaleY).toDouble()));
1219  }
1222 
1223  return ossimConnectableObject::loadState(kwl, prefix);
1224 }
1225 
1227  const char* prefix)const
1228 {
1229  ossimString resamplerType;
1231  {
1232  resamplerType = "BICUBIC";
1233  }
1235  {
1236  resamplerType = "BILINEAR";
1237  }
1238  else
1239  {
1240  resamplerType = "NEAREST_NEIGHBOR";
1241  }
1242  kwl.add(prefix,
1243  RESAMPLER_CONVOLUTION_TYPE_KW,
1244  resamplerType.c_str(),
1245  true);
1246 
1247  kwl.add(prefix,
1248  RESAMPLER_SCALE_X_KW,
1250  true);
1251 
1252  kwl.add(prefix,
1253  RESAMPLER_SCALE_Y_KW,
1255  true);
1256 
1257  kwl.add(prefix,
1258  RESAMPLER_CUBIC_PARAMETER_KW,
1260  true);
1261 
1262  return ossimConnectableObject::saveState(kwl, prefix);
1263 }
virtual void resampleNearestNeighbor(ossimImageData *input, ossimImageData *output, const ossimIrect &outputSubRect, const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &deltaUl, const ossimDpt &deltaUr, const ossimDpt &length)
16 bit unsigned integer (15 bits used)
virtual ossim_uint32 getWidth() const
ossim_uint32 x
ossim_int32 theTableWidthY
virtual const ossim_float64 * getMaxPix() const
ossim_int32 theTableWidthX
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
virtual ossim_uint32 getNumberOfBands() const
void resampleTile(T, ossimImageData *input, ossimImageData *output)
64 bit floating point
16 bit unsigned integer
Represents serializable keyword/value map.
ossim_uint32 y
const char * find(const char *key) const
float ossim_float32
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
const ossimDpt & ul() const
Definition: ossimDrect.h:339
double y
Definition: ossimDpt.h:165
ossim_int32 theTableHeight
ossim_uint32 height() const
Definition: ossimIrect.h:487
virtual void setResamplerType(ossimResLevelResamplerType type)
double theCubicAdjustableParameter
virtual void generateWeightTable()
16 bit signed integer
void resampleFullTile(T, ossimImageData *input, ossimImageData *output)
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
16 bit unsigned integer (14 bits used)
virtual ossimResLevelResamplerType getResamplerType() const
16 bit unsigned integer (13 bits used)
32 bit floating point
unsigned short ossim_uint16
32 bit unsigned integer
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual void initialize()
Initialize the data buffer.
virtual ~ossimResampler()
bool isNull(ossim_uint32 offset) const
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
ossim_int32 theKernelWidth
double getCubicC2(double t) const
double ** theWeightTableX
virtual void resample(ossimImageData *input, ossimImageData *output)
signed short ossim_sint16
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
double toDouble() const
virtual ossimIrect getImageRectangle() const
double getCubicC0(double t) const
virtual ossim_int32 getKernelWidth() const
ossim_uint32 width() const
Definition: ossimIrect.h:500
ossimScalarType
virtual void setOrigin(const ossimIpt &origin)
virtual const ossim_float64 * getMinPix() const
ossimDpt theOutputToInputRatio
virtual ossimScalarType getScalarType() const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
64 bit normalized floating point
16 bit unsigned integer (11 bits used)
void setRatio(double outputToInputRatio)
double ** theWeightTableY
#define max(a, b)
Definition: auxiliary.h:76
ossim_int32 y
Definition: ossimIpt.h:142
virtual const void * getBuf() const
double getCubicC1(double t) const
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
double getCubicC3(double t) const
double x
Definition: ossimDpt.h:164
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
void resampleTileNearestNeighbor(T, ossimImageData *input, ossimImageData *output, const ossimDpt &ul, const ossimDpt &ur, const ossimDpt &deltaUl, const ossimDpt &deltaUr, const ossimDpt &length)
ossim_int32 x
Definition: ossimIpt.h:141
8 bit unsigned integer
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual void deleteWeightTable()
void resamplePartialTile(T, ossimImageData *input, ossimImageData *output)
const ossimDpt & lr() const
Definition: ossimDrect.h:341
ossimResLevelResamplerType theResamplerType
16 bit signed integer
virtual const ossimIpt & getOrigin() const
unsigned char ossim_uint8
virtual ossim_int32 getKernelHeight() const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
int ossim_int32
virtual void allocateWeightTable()
ossim_int32 theKernelHeight
16 bit unsigned integer (12 bits used)
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91