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