1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License:  LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Garrett Potts
9 
10 // Contributor:
11 //         David A. Horner (DAH) http://dave.thehorners.com
12 //
13 //*************************************************************************
14 // $Id: ossimFilterResampler.cpp 23586 2015-10-19 10:45:22Z gpotts $
15 
16 #include <ossim/imaging/ossimFilterResampler.h>
17 #include <ossim/base/ossimCommon.h>
18 #include <ossim/base/ossimPreferences.h>
19 #include <ossim/base/ossimKeywordNames.h>
20 #include <ossim/base/ossimKeywordlist.h>
21 #include <ossim/imaging/ossimImageDataFactory.h>
22 #include <ossim/base/ossimDpt.h>
23 #include <ossim/base/ossimDrect.h>
24 #include <ossim/imaging/ossimFilterTable.h>
25 
26 using namespace std;
27 
ossimFilterResampler()28 ossimFilterResampler::ossimFilterResampler()
29    :theMinifyFilter(new ossimNearestNeighborFilter()),
30     theMagnifyFilter(new ossimNearestNeighborFilter()),
31     theMinifyFilterType(ossimFilterResampler_NEAREST_NEIGHBOR),
32     theMagnifyFilterType(ossimFilterResampler_NEAREST_NEIGHBOR),
33     theScaleFactor(1.0, 1.0),
34     theInverseScaleFactor(1.0, 1.0),
35     theBlurFactor(1.0)
36 {
37    setScaleFactor(ossimDpt(1.0, 1.0));
38    loadState(ossimPreferences::instance()->preferencesKWL(),"resampler.");
39 
40 }
41 
~ossimFilterResampler()42 ossimFilterResampler::~ossimFilterResampler()
43 {
44    if(theMinifyFilter)
45    {
46       delete theMinifyFilter;
47       theMinifyFilter = NULL;
48    }
49    if(theMagnifyFilter)
50    {
51       delete theMagnifyFilter;
52       theMagnifyFilter = NULL;
53    }
54 }
55 
56 
resample(const ossimRefPtr<ossimImageData> & input,ossimRefPtr<ossimImageData> & output,const ossimDpt & ul,const ossimDpt & ur,const ossimDpt & deltaUl,const ossimDpt & deltaUr,const ossimDpt & length)57 void ossimFilterResampler::resample(const ossimRefPtr<ossimImageData>& input,
58 				    ossimRefPtr<ossimImageData>& output,
59 				    const ossimDpt& ul,
60 				    const ossimDpt& ur,
61 				    const ossimDpt& deltaUl,
62 				    const ossimDpt& deltaUr,
63 				    const ossimDpt& length)
64 {
65    resample(input,
66             output,
67             output->getImageRectangle(),
68             ul,
69             ur,
70             deltaUl,
71             deltaUr,
72             length);
73 }
74 
resample(const ossimRefPtr<ossimImageData> & input,ossimRefPtr<ossimImageData> & output,const ossimIrect & outputSubRect,const ossimDpt & ul,const ossimDpt & ur,const ossimDpt & deltaUl,const ossimDpt & deltaUr,const ossimDpt & length)75 void ossimFilterResampler::resample(const ossimRefPtr<ossimImageData>& input,
76 				    ossimRefPtr<ossimImageData>& output,
77 				    const ossimIrect& outputSubRect,
78 				    const ossimDpt& ul,
79 				    const ossimDpt& ur,
80 				    const ossimDpt& deltaUl,
81 				    const ossimDpt& deltaUr,
82 				    const ossimDpt& length)
83 {
84    if(!input.valid()   ||
85       !output.valid()  ||
86       !input->getBuf() ||
87       !output->getBuf())
88    {
89       return;
90    }
91 
92    ossimScalarType scalarType = input->getScalarType();
93    switch(scalarType)
94    {
95       case OSSIM_UINT8:
96       {
97          resampleBilinearTile(ossim_uint8(0), // dummy template variable
98 			      input,
99 			      output,
100 			      outputSubRect,
101 			      ul,
102 			      ur,
103 			      deltaUl,
104 			      deltaUr,
105 			      length);
106          break;
107       }
108       case OSSIM_SINT8:
109       {
110          resampleBilinearTile(ossim_sint8(0), // dummy template variable
111 			      input,
112 			      output,
113 			      outputSubRect,
114 			      ul,
115 			      ur,
116 			      deltaUl,
117 			      deltaUr,
118 			      length);
119          break;
120       }
121       case OSSIM_UINT16:
122       case OSSIM_USHORT11:
123       case OSSIM_USHORT12:
124       case OSSIM_USHORT13:
125       case OSSIM_USHORT14:
126       case OSSIM_USHORT15:
127       {
128 	 resampleBilinearTile(ossim_uint16(0), // dummy template variable
129 			      input,
130 			      output,
131 			      outputSubRect,
132 			      ul,
133 			      ur,
134 			      deltaUl,
135 			      deltaUr,
136 			      length);
137 	 break;
138       }
139       case OSSIM_SINT16:
140       {
141 	 resampleBilinearTile(ossim_sint16(0), // dummy template variable
142 			      input,
143 			      output,
144 			      outputSubRect,
145 			      ul,
146 			      ur,
147 			      deltaUl,
148 			      deltaUr,
149 			      length);
150 	 break;
151       }
152       case OSSIM_UINT32:
153       {
154 	 resampleBilinearTile(ossim_uint32(0), // dummy template variable
155 			      input,
156 			      output,
157 			      outputSubRect,
158 			      ul,
159 			      ur,
160 			      deltaUl,
161 			      deltaUr,
162 			      length);
163 	 break;
164       }
165       case OSSIM_SINT32:
166       {
167 	 resampleBilinearTile(ossim_sint32(0), // dummy template variable
168 			      input,
169 			      output,
170 			      outputSubRect,
171 			      ul,
172 			      ur,
173 			      deltaUl,
174 			      deltaUr,
175 			      length);
176 	 break;
177       }
178       case OSSIM_FLOAT32:
179       case OSSIM_NORMALIZED_FLOAT:
180       {
181 	 resampleBilinearTile(ossim_float32(0.0), // dummy template variable
182 			      input,
183 			      output,
184 			      outputSubRect,
185 			      ul,
186                ur,
187 			      deltaUl,
188 			      deltaUr,
189 			      length);
190 	 break;
191       }
192       case OSSIM_FLOAT64:
193       case OSSIM_NORMALIZED_DOUBLE:
194       {
195 	 resampleBilinearTile(ossim_float64(0.0), // dummy template variable
196 			      input,
197 			      output,
198 			      outputSubRect,
199 			      ul,
200 			      ur,
201 			      deltaUl,
202 			      deltaUr,
203 			      length);
204          break;
205       }
206       default:
207       {
208          ossimNotify(ossimNotifyLevel_WARN)
209             << "ossimFilterResampler::resample error: unknown scalar type:  "
210             << scalarType << endl;
211       }
212    }
213 }
214 
215 
createNewFilter(ossimFilterResamplerType filterType,ossimFilterResamplerType & result)216 ossimFilter* ossimFilterResampler::createNewFilter(
217    ossimFilterResamplerType filterType,
218    ossimFilterResamplerType& result)
219 {
220    switch(filterType)
221    {
222       case ossimFilterResampler_NEAREST_NEIGHBOR:
223       {
224          return new ossimNearestNeighborFilter();
225       }
226       case ossimFilterResampler_BOX:
227       {
228          return new ossimBoxFilter();
229       }
230       case ossimFilterResampler_GAUSSIAN:
231       {
232          return new ossimGaussianFilter();
233       }
234       case ossimFilterResampler_CUBIC:
235       {
236          return new ossimCubicFilter();
237       }
238       case ossimFilterResampler_HANNING:
239       {
240          return new ossimHanningFilter();
241       }
242       case ossimFilterResampler_HAMMING:
243       {
244          return new ossimHammingFilter();
245       }
246       case ossimFilterResampler_LANCZOS:
247       {
248          return new ossimLanczosFilter();
249       }
250       case ossimFilterResampler_CATROM:
251       {
252          return new ossimCatromFilter();
253       }
254       case ossimFilterResampler_MITCHELL:
255       {
256          return new ossimMitchellFilter();
257       }
258       case ossimFilterResampler_BLACKMAN:
259       {
260          return new ossimBlackmanFilter();
261       }
262       case ossimFilterResampler_BLACKMAN_SINC:
263       {
264          return new ossimBlackmanSincFilter();
265       }
266       case ossimFilterResampler_BLACKMAN_BESSEL:
267       {
268          return new ossimBlackmanBesselFilter();
269       }
270       case ossimFilterResampler_QUADRATIC:
271       {
272          return new ossimQuadraticFilter();
273       }
274       case ossimFilterResampler_TRIANGLE:
275       {
276          return new ossimTriangleFilter();
277       }
278       case ossimFilterResampler_HERMITE:
279       {
280          return new ossimHermiteFilter();
281       }
282       case ossimFilterResampler_BELL:
283       {
284          return new ossimGaussianFilter();
285       }
286       case ossimFilterResampler_BSPLINE:
287       {
288          return new ossimBSplineFilter();
289       }
290       case ossimFilterResampler_MAGIC:
291       {
292          return new ossimBSplineFilter();
293       }
294    }
295 
296    result = ossimFilterResampler_NEAREST_NEIGHBOR;
297    return new ossimNearestNeighborFilter();
298 }
299 
setScaleFactor(const ossimDpt & scale)300 void ossimFilterResampler::setScaleFactor(const ossimDpt& scale)
301 {
302    theScaleFactor = scale;
303    if(fabs(theScaleFactor.x) <= FLT_EPSILON)
304    {
305       theScaleFactor.x = 1.0;
306    }
307    if(fabs(theScaleFactor.y) <= FLT_EPSILON)
308    {
309       theScaleFactor.y = 1.0;
310    }
311 
312    theInverseScaleFactor.x = 1.0/theScaleFactor.x;
313    theInverseScaleFactor.y = 1.0/theScaleFactor.y;
314 }
315 
resampleBilinearTile(T,const ossimRefPtr<ossimImageData> & input,ossimRefPtr<ossimImageData> & output,const ossimIrect & outputSubRect,const ossimDpt & inputUl,const ossimDpt & inputUr,const ossimDpt & deltaUl,const ossimDpt & deltaUr,const ossimDpt & outLength)316 template <class T> void ossimFilterResampler::resampleBilinearTile(
317    T /* dummy */,
318    const ossimRefPtr<ossimImageData>& input,
319    ossimRefPtr<ossimImageData>& output,
320    const ossimIrect& outputSubRect,
321    const ossimDpt& inputUl,
322    const ossimDpt& inputUr,
323    const ossimDpt& deltaUl,
324    const ossimDpt& deltaUr,
325    const ossimDpt& outLength)
326 {
327 #if 0 /* Please leave for debug. */
328    std::cout << "INPUT  = \n" << *input << std::endl
329              << "OUTPUT = \n" << *output << std::endl
330              << "inputUL= " << inputUl << std::endl
331              << "inputUR= " << inputUr << std::endl
332              << "deltaUL= " << deltaUl << std::endl
333              << "deltaUr= " << deltaUr << std::endl
334              << "outlength= " << outLength << std::endl;
335 #endif
336 
337    ossim_uint32  band, centerOffset;
338    ossim_float64 tmpFlt64, stepSizeWidth;
339 
340    if(outLength.x>1) {
341       stepSizeWidth  = 1.0/(outLength.x-1.0);
342    } else {
343       stepSizeWidth   = 1.0;
344    }
345 
346    // INPUT INFORMATION
347    ossim_uint32       inWidth      = input->getWidth();
348    ossim_uint32       inBandSize   = input->getSizePerBand();  // fix for out-of-bounds check OLK 06/2005
349    ossim_uint32       BANDS        = input->getNumberOfBands();
350    ossimIrect         inputRect    = input->getImageRectangle();
351 
352    // OUTPUT INFORMATION
353    const ossim_float64* NULL_PIX      = output->getNullPix();
354    const ossim_float64* MIN_PIX       = output->getMinPix();
355    const ossim_float64* MAX_PIX       = output->getMaxPix();
356    ossimIrect           outputRect    = output->getImageRectangle();
357    ossim_uint32         resultRectH   = outputSubRect.height();
358    ossim_uint32         resultRectW   = outputSubRect.width();
359    ossim_uint32         outputRectW   = outputRect.width();
360 
361    // calculate the offset into the data so we can refer to it at 0 index.
362    ossim_uint32 resultOffset=(outputSubRect.ul().y - outputRect.ul().y)*outputRectW +
363                              (outputSubRect.ul().x - outputRect.ul().x);
364 
365    // make a local copy of the band pointers (at resultOffset)
366    ossim_float64 *densityvals=new ossim_float64[BANDS];
367    ossim_float64 *pixelvals=new ossim_float64[BANDS];
368    const T* *inputBuf  = new const T*[BANDS];
369    T* *resultBuf = new T*[BANDS];
370    if(!pixelvals||!inputBuf||!resultBuf)
371    {
372       return;
373    }
374 
375    for(band = 0; band < BANDS; ++band)
376    {
377       inputBuf[band] = static_cast<const T*>(input->getBuf(band));
378       resultBuf[band] = static_cast<T*>(output->getBuf(band))+resultOffset;
379    }
380 
381    // FILTER INFORMAION
382    ossim_uint32 xkernel_width  = theFilterTable.getWidth();;
383    ossim_uint32 ykernel_height = theFilterTable.getHeight();
384    double xkernel_half_width   = theFilterTable.getXSupport();
385    double ykernel_half_height  = theFilterTable.getYSupport();
386 
387    double initialx  = inputUl.x-inputRect.ul().x;
388    double initialy  = inputUl.y-inputRect.ul().y;
389    double terminalx = inputUr.x-inputRect.ul().x;
390    double terminaly = inputUr.y-inputRect.ul().y;
391    double pointx,pointy,deltaX,deltaY;
392    ossim_int32 starty,startx;
393 
394    if(xkernel_width==0 || ykernel_height==0)
395    {
396       // USING NEAREST NEIGHBOR
397       for(ossim_uint32 resultY = 0; resultY < resultRectH; ++resultY)
398       {
399 //          deltaX = (terminalx-initialx) * stepSizeWidth;
400 //          deltaY = (terminaly-initialy) * stepSizeHeight;
401          // this should be stepsize width for both since we are traversing horizontal
402          deltaX = (terminalx-initialx) * stepSizeWidth;
403          deltaY = (terminaly-initialy) * stepSizeWidth;
404          pointx = initialx;
405          pointy = initialy;
406          for(ossim_uint32 resultX = 0; resultX < resultRectW; ++resultX)
407          {
408             // just sample center in input space.
409             centerOffset = ossim::round<int>(pointy)*inWidth + ossim::round<int>(pointx);
410             for(band=0;band<BANDS;++band)
411             {
412                resultBuf[band][resultX] = inputBuf[band][centerOffset];
413             }
414             pointy += deltaY;
415             pointx += deltaX;
416          } // End of loop in x direction.
417 
418          // increment pointers to where we are now.
419          for(band=0;band<BANDS;++band)
420          {
421             resultBuf[band] += outputRectW;
422          }
423          initialx += deltaUl.x;
424          initialy += deltaUl.y;
425          terminalx  += deltaUr.x;
426          terminaly  += deltaUr.y;
427       } // End of loop in y direction.
428 
429    }
430    else
431    {
432       // USING A KERNEL
433       const double* kernel;
434       ossim_uint32 iy,ix,sourceIndex,nullCount;
435       for(ossim_uint32 resultY = 0; resultY < resultRectH; ++resultY)
436       {
437          deltaX = (terminalx-initialx) * stepSizeWidth;
438          deltaY = (terminaly-initialy) * stepSizeWidth;
439          pointx = initialx;
440          pointy = initialy;
441          for(ossim_uint32 resultX = 0; resultX < resultRectW; ++resultX)
442          {
443             starty  = ossim::round<int>(pointy - ykernel_half_height + .5);
444             startx  = ossim::round<int>(pointx - xkernel_half_width + .5);
445             centerOffset = ossim::round<int>(pointy)*inWidth + ossim::round<int>(pointx);
446             sourceIndex = starty*inWidth+startx;
447 
448             // look at center pixel, make sure they aren't all null.
449             nullCount=0;
450             if(centerOffset<inBandSize)
451             {
452                for (band=0;band<BANDS;++band)
453                {
454                   if(inputBuf[band][centerOffset]==static_cast<T>(NULL_PIX[band]))
455                   {
456                      ++nullCount;
457                   }
458                }
459                // the center of the kernel is outside the input space, just set null.
460             }
461             else
462             {
463                nullCount=BANDS;
464             }
465 
466             // make sure we have non-null data and we fit within the inputBuf.
467             if ( nullCount==BANDS || (sourceIndex>=inBandSize))
468             {
469                // we don't need to continue, just assign null!
470                for (band=0;band<BANDS;++band)
471                {
472                   resultBuf[band][resultX] = static_cast<T>(NULL_PIX[band]);
473                }
474             }
475             else
476             {
477                kernel = theFilterTable.getClosestWeights(pointx,pointy);
478                if(kernel)
479                {
480                   // reset the pixel/density sums for each band to zero.
481                   memset(densityvals,'\0',sizeof(ossim_float64)*BANDS);
482                   memset(pixelvals,'\0',sizeof(ossim_float64)*BANDS);
483 
484                   // apply kernel to input space.
485                   for (iy=0;((iy<ykernel_height)&&(sourceIndex<inBandSize));++iy)
486                   {
487                      for (ix = 0;((ix<xkernel_width)&&(sourceIndex<inBandSize));++ix)
488                      {
489                         tmpFlt64=*kernel; // pixel weight;
490                         for(band=0;band<BANDS;++band)
491                         {
492                            if(inputBuf[band][sourceIndex]!=NULL_PIX[band])
493                            {
494                               densityvals[band] += tmpFlt64;
495                               pixelvals[band] += (inputBuf[band][sourceIndex]*tmpFlt64);
496                            }
497                         }
498                         ++sourceIndex;
499                         ++kernel;
500                         if(sourceIndex>=inBandSize)
501                         {
502                            break;
503                         }
504                      }
505                      sourceIndex+=(inWidth-xkernel_width);
506                   }
507 
508                   // actually assign the value to the output
509                   for (band = 0; band < BANDS; ++band)
510                   {
511                      if(densityvals[band]<=FLT_EPSILON)
512                      {
513                         //---
514                         // Setting tempFlt64 to pixelvals[band] causing 0's where -32768
515                         // should be when null check was skipped above.
516                         // tmpFlt64 = pixelvals[band];
517                         //---
518                         tmpFlt64 = NULL_PIX[band];
519                      }
520                      else
521                      {
522                         // normalize
523                         tmpFlt64 = pixelvals[band]/densityvals[band];
524                      }
525 
526                      // clamp
527                      tmpFlt64 = (tmpFlt64>=MIN_PIX[band]?(tmpFlt64<MAX_PIX[band]?tmpFlt64:MAX_PIX[band]):MIN_PIX[band]);
528                      // set resultant pixel value.
529                      resultBuf[band][resultX] = static_cast<T>(tmpFlt64);
530                   }
531 
532                   // we didn't get a filter kernel, just set NULL in this disaster.
533                }
534                else
535                {
536                   for (band=0;band<BANDS;++band)
537                   {
538                      resultBuf[band][resultX] = static_cast<T>(NULL_PIX[band]);
539                   }
540                }
541             }
542             pointy += deltaY;
543             pointx += deltaX;
544          } // End of loop in x direction.
545 
546          // increment pointers to where we are now.
547          for(band=0;band<BANDS;++band)
548          {
549             resultBuf[band] += outputRectW;
550          }
551          initialx += deltaUl.x;
552          initialy += deltaUl.y;
553          terminalx  += deltaUr.x;
554          terminaly  += deltaUr.y;
555       } // End of loop in y direction.
556    } // USING A KERNEL END
557 
558    delete [] densityvals;
559    delete [] pixelvals;
560    delete [] resultBuf;
561    delete [] inputBuf;
562 }
563 
getFilterTypeAsString(ossimFilterResamplerType type) const564 ossimString ossimFilterResampler::getFilterTypeAsString(ossimFilterResamplerType type)const
565 {
566    switch(type)
567    {
568       case ossimFilterResampler_NEAREST_NEIGHBOR:
569       {
570          return "nearest neighbor";
571       }
572       case ossimFilterResampler_BOX:
573       {
574          return "box";
575       }
576       case ossimFilterResampler_GAUSSIAN:
577       {
578          return "gaussian";
579       }
580       case ossimFilterResampler_CUBIC:
581       {
582          return "cubic";
583       }
584       case ossimFilterResampler_HANNING:
585       {
586          return "hanning";
587       }
588       case ossimFilterResampler_HAMMING:
589       {
590          return "hamming";
591       }
592       case ossimFilterResampler_LANCZOS:
593       {
594          return "lanczos";
595       }
596       case ossimFilterResampler_MITCHELL:
597       {
598          return "mitchell";
599       }
600       case ossimFilterResampler_CATROM:
601       {
602          return "catrom";
603       }
604       case ossimFilterResampler_BLACKMAN:
605       {
606          return "blackman";
607       }
608       case ossimFilterResampler_BLACKMAN_SINC:
609       {
610          return "sinc";
611       }
612       case ossimFilterResampler_BLACKMAN_BESSEL:
613       {
614          return "bessel";
615       }
616       case ossimFilterResampler_QUADRATIC:
617       {
618          return "quadratic";
619       }
620       case ossimFilterResampler_TRIANGLE:
621       {
622          return "bilinear";
623       }
624       case ossimFilterResampler_HERMITE:
625       {
626          return "hermite";
627       }
628       case ossimFilterResampler_BELL:
629       {
630          return "gaussian";
631       }
632       case ossimFilterResampler_BSPLINE:
633       {
634          return "bspline";
635       }
636       case ossimFilterResampler_MAGIC:
637       {
638          return "magic";
639       }
640    }
641 
642    return "nearest neighbor";
643 }
644 
getFilterTypes(std::vector<ossimString> & filterTypes) const645 void ossimFilterResampler::getFilterTypes(std::vector<ossimString>& filterTypes)const
646 {
647   filterTypes.push_back("nearest neighbor");
648   filterTypes.push_back("bilinear");
649   filterTypes.push_back("cubic");
650 //  filterTypes.push_back("bell");
651   filterTypes.push_back("bessel");
652   filterTypes.push_back("blackman");
653   filterTypes.push_back("box");
654   filterTypes.push_back("bspline");
655   filterTypes.push_back("catrom");
656   filterTypes.push_back("gaussian");
657   filterTypes.push_back("hanning");
658   filterTypes.push_back("hamming");
659   filterTypes.push_back("hermite");
660   filterTypes.push_back("lanczos");
661   filterTypes.push_back("mitchell");
662   filterTypes.push_back("quadratic");
663   filterTypes.push_back("sinc");
664   filterTypes.push_back("magic");
665 }
666 
667 
getFilterType(const ossimString & type) const668 ossimFilterResampler::ossimFilterResamplerType ossimFilterResampler::getFilterType(const ossimString& type)const
669 {
670    ossimString typeUpper = type;
671    typeUpper = typeUpper.upcase();
672 
673    if(typeUpper.contains("BOX"))
674    {
675       return ossimFilterResampler_BOX;
676    }
677    else if(typeUpper.contains("NEAREST"))
678    {
679       return ossimFilterResampler_NEAREST_NEIGHBOR;
680    }
681    else if(typeUpper.contains("GAUSSIAN"))
682    {
683       return ossimFilterResampler_GAUSSIAN;
684    }
685    else if(typeUpper.contains("HANNING"))
686    {
687       return ossimFilterResampler_HANNING;
688    }
689    else if(typeUpper.contains("HAMMING"))
690    {
691       return ossimFilterResampler_HAMMING;
692    }
693    else if(typeUpper.contains("LANCZOS"))
694    {
695       return ossimFilterResampler_LANCZOS;
696    }
697    else if(typeUpper.contains("MITCHELL"))
698    {
699       return ossimFilterResampler_MITCHELL;
700    }
701    else if(typeUpper.contains("CATROM"))
702    {
703       return ossimFilterResampler_CATROM;
704    }
705    else if(typeUpper.contains("CUBIC"))
706    {
707       return ossimFilterResampler_CUBIC;
708    }
709    else if(typeUpper.contains("BESSEL"))
710    {
711       return ossimFilterResampler_BLACKMAN_BESSEL;
712    }
713    else if(typeUpper.contains("SINC"))
714    {
715       return ossimFilterResampler_BLACKMAN_SINC;
716    }
717    else if(typeUpper.contains("BLACKMAN"))
718    {
719       return ossimFilterResampler_BLACKMAN;
720    }
721    else if(typeUpper.contains("QUADRATIC"))
722    {
723       return ossimFilterResampler_QUADRATIC;
724    }
725    else if(typeUpper.contains("TRIANGLE"))
726    {
727       return ossimFilterResampler_TRIANGLE;
728    }
729    else if(typeUpper.contains("BILINEAR"))
730    {
731       return ossimFilterResampler_TRIANGLE;
732    }
733    else if(typeUpper.contains("HERMITE"))
734    {
735       return ossimFilterResampler_HERMITE;
736    }
737 //    else if(typeUpper.contains("BELL"))
738 //    {
739 //       return ossimFilterResampler_BELL;
740 //    }
741    else if(typeUpper.contains("BSPLINE"))
742    {
743       return ossimFilterResampler_BSPLINE;
744    }
745    else if(typeUpper.contains("MAGIC"))
746    {
747       return ossimFilterResampler_MAGIC;
748    }
749 
750    return ossimFilterResampler_NEAREST_NEIGHBOR;
751 }
752 
getKernelSupport(double & x,double & y) const753 void ossimFilterResampler::getKernelSupport(double& x, double& y)const
754 {
755    const ossimFilter* horizontalFilter = getHorizontalFilter();
756    const ossimFilter* verticalFilter   = getVerticalFilter();
757 
758    if(!horizontalFilter)
759    {
760       x = 0.0;
761    }
762    else
763    {
764 //       x = theBlurFactor*ossim::max(1.0/theScaleFactor.x, 1.0)*
765 //           horizontalFilter->getSupport();
766       x = horizontalFilter->getSupport();
767    }
768 
769    if(!verticalFilter)
770    {
771       y = 0.0;
772    }
773    else
774    {
775 //       y = theBlurFactor*ossim::max(1.0/theScaleFactor.y, 1.0)*
776 //           verticalFilter->getSupport();
777       y = verticalFilter->getSupport();
778    }
779 }
780 
getHorizontalFilter() const781 const ossimFilter* ossimFilterResampler::getHorizontalFilter()const
782 {
783    if(theScaleFactor.x < 1)
784    {
785       return theMinifyFilter;
786    }
787 
788    return theMagnifyFilter;
789 }
790 
getVerticalFilter() const791 const ossimFilter* ossimFilterResampler::getVerticalFilter()const
792 {
793    if(theScaleFactor.y < 1)
794    {
795       return theMinifyFilter;
796    }
797 
798    return theMagnifyFilter;
799 }
800 
setFilterType(const ossimString & type)801 void ossimFilterResampler::setFilterType(const ossimString& type)
802 {
803    setFilterType(type, type);
804 }
805 
setFilterType(ossimFilterResamplerType filterType)806 void ossimFilterResampler::setFilterType(ossimFilterResamplerType filterType)
807 {
808    setFilterType(filterType, filterType);
809 }
setFilterType(const ossimString & minifyType,const ossimString & magnifyType)810 void ossimFilterResampler::setFilterType(const ossimString& minifyType,
811                                          const ossimString& magnifyType)
812 {
813    setFilterType(getFilterType(minifyType),
814                  getFilterType(magnifyType));
815 }
816 
setMinifyFilterType(const ossimString & minifyType)817 void ossimFilterResampler::setMinifyFilterType(const ossimString& minifyType)
818 {
819    setMinifyFilterType(getFilterType(minifyType));
820 }
821 
setMagnifyFilterType(const ossimString & magnifyType)822 void ossimFilterResampler::setMagnifyFilterType(const ossimString& magnifyType)
823 {
824    setMagnifyFilterType(getFilterType(magnifyType));
825 }
826 
setMinifyFilterType(ossimFilterResamplerType filterType)827 void ossimFilterResampler::setMinifyFilterType(ossimFilterResamplerType filterType)
828 {
829    setFilterType(filterType,
830                  theMagnifyFilterType);
831 }
832 
setMagnifyFilterType(ossimFilterResamplerType filterType)833 void ossimFilterResampler::setMagnifyFilterType(ossimFilterResamplerType filterType)
834 {
835    setFilterType(theMinifyFilterType,filterType);
836 }
837 
getMinifyFilterTypeAsString() const838 ossimString ossimFilterResampler::getMinifyFilterTypeAsString()const
839 {
840    return getFilterTypeAsString(theMinifyFilterType);
841 }
842 
getMagnifyFilterTypeAsString() const843 ossimString ossimFilterResampler::getMagnifyFilterTypeAsString()const
844 {
845    return getFilterTypeAsString(theMagnifyFilterType);
846 }
847 
setFilterType(ossimFilterResamplerType minifyFilterType,ossimFilterResamplerType magnifyFilterType)848 void ossimFilterResampler::setFilterType(
849    ossimFilterResamplerType minifyFilterType,
850    ossimFilterResamplerType magnifyFilterType)
851 {
852    if(theMinifyFilter)
853    {
854       delete theMinifyFilter;
855       theMinifyFilter = NULL;
856    }
857    if(theMagnifyFilter)
858    {
859       delete theMagnifyFilter;
860       theMagnifyFilter = NULL;
861    }
862 
863    theMinifyFilterType  = minifyFilterType;
864    theMagnifyFilterType = magnifyFilterType;
865 
866    theMinifyFilter  = createNewFilter(minifyFilterType, theMinifyFilterType);
867    theMagnifyFilter = createNewFilter(magnifyFilterType, theMagnifyFilterType);
868    computeTable();
869 }
870 
getBlurFactor() const871 ossim_float64 ossimFilterResampler::getBlurFactor()const
872 {
873    return theBlurFactor;
874 }
875 
setBlurFactor(ossim_float64 blur)876 void ossimFilterResampler::setBlurFactor(ossim_float64 blur)
877 {
878    theBlurFactor = blur;
879 }
880 
saveState(ossimKeywordlist & kwl,const char * prefix) const881 bool ossimFilterResampler::saveState(ossimKeywordlist& kwl,
882                                      const char* prefix)const
883 {
884    kwl.add(prefix,
885            ossimKeywordNames::SCALE_X_KW,
886            theScaleFactor.x,
887            true);
888    kwl.add(prefix,
889            ossimKeywordNames::SCALE_Y_KW,
890            theScaleFactor.y,
891            true);
892    kwl.add(prefix,
893            "minify_type",
894            getFilterTypeAsString(theMinifyFilterType),
895            true);
896    kwl.add(prefix,
897            "magnify_type",
898            getFilterTypeAsString(theMagnifyFilterType),
899            true);
900 
901    return true;
902 }
903 
loadState(const ossimKeywordlist & kwl,const char * prefix)904 bool ossimFilterResampler::loadState(const ossimKeywordlist& kwl,
905                                      const char* prefix)
906 {
907    const char* lookup = 0;
908 
909    lookup = kwl.find(prefix, ossimKeywordNames::SCALE_X_KW);
910    if (lookup)
911    {
912       theScaleFactor.x = ossimString(lookup).toDouble();
913    }
914 
915    lookup = kwl.find(prefix, ossimKeywordNames::SCALE_Y_KW);
916    if (lookup)
917    {
918       theScaleFactor.y = ossimString(lookup).toDouble();
919    }
920 
921    lookup = kwl.find(prefix, "minify_type");
922    if (lookup)
923    {
924       setMinifyFilterType(lookup);
925    }
926 
927    lookup = kwl.find(prefix, "magnify_type");
928    if (lookup)
929    {
930       setMagnifyFilterType(lookup);
931    }
932 
933    if(fabs(theScaleFactor.x) <= FLT_EPSILON)
934    {
935       theScaleFactor.x = 1.0;
936    }
937    if(fabs(theScaleFactor.y) <= FLT_EPSILON)
938    {
939       theScaleFactor.y = 1.0;
940    }
941 
942    theInverseScaleFactor.x = 1.0/theScaleFactor.x;
943    theInverseScaleFactor.y = 1.0/theScaleFactor.y;
944 
945    return true;
946 }
947 
computeTable()948 void ossimFilterResampler::computeTable()
949 {
950   theFilterTable.buildTable(32, *theMagnifyFilter);
951 }
952 
953