OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimBandClipFilter.cpp
Go to the documentation of this file.
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 //*************************************************************************
11 // $Id: ossimBandClipFilter.cpp 21631 2012-09-06 18:10:55Z dburken $
12 
16 
18 
21  theClipType(ossimBandClipType_NONE),
22  theTile(NULL)
23 {
24  theTile = new ossimImageData(this, // I am the owner,
26  1);
28 }
29 
31  const vector<double>& minPix,
32  const vector<double>& maxPix,
33  ossimBandClipType clipType)
34  :ossimImageSourceFilter(inputSource),
35  theClipType(clipType),
36  theTile(NULL)
37 {
38  theTile = new ossimImageData(this, // I am the owner,
40  1);
42  setMinMaxPix(minPix, maxPix);
43 }
44 
46  double minPix,
47  double maxPix,
48  ossimBandClipType clipType)
49  :ossimImageSourceFilter(inputSource),
50  theClipType(clipType),
51  theTile(NULL)
52 {
53  theTile = new ossimImageData(this, // I am the owner,
55  1);
57 
58  theMinPix.push_back(minPix);
59  theMaxPix.push_back(maxPix);
60 }
61 
63 {
64 }
65 
67 {
68  theClipType = clipType;
69 }
70 
72 {
73  return theClipType;
74 }
75 
77 {
78  // We make sure that all arrays have the same number
79  // of elements so we can use the size of any of them.
80  return (ossim_uint32)theMinPix.size();
81 }
82 
84 {
85 
86  // lets do a non destructive set. That way we can
87  // grow or shrink the list without destroying
88  // the original values.
89  //
90  if(!size)
91  {
92  theMinPix.clear();
93  theMaxPix.clear();
94  theMedian.clear();
95  return;
96  }
97 
98 
99  vector<double> tempMin = theMinPix;
100  vector<double> tempMax = theMaxPix;
101 
102  theMinPix.resize(size);
103  theMaxPix.resize(size);
104  theMedian.resize(size);
105 
106  ossim_uint32 upperBound = (ossim_uint32)min(theMinPix.size(), tempMin.size());
107  ossim_uint32 index = 0;
108 
109  for(index = 0; index < upperBound; ++index)
110  {
111  theMinPix[index] = tempMin[index];
112  theMaxPix[index] = tempMax[index];
113 
114  theMinPix[index] = theMinPix[index]>1?1:theMinPix[index];
115  theMinPix[index] = theMinPix[index]<0?0:theMinPix[index];
116  theMaxPix[index] = theMaxPix[index]>1?1:theMaxPix[index];
117  theMaxPix[index] = theMaxPix[index]<0?0:theMaxPix[index];
118 
119  theMedian[index] = (theMaxPix[index] + theMinPix[index])/2.0;
120  }
121 
122  for(;index < theMinPix.size();++index)
123  {
126  theMedian[index] = (theMaxPix[index] + theMinPix[index])/2.0;
127 
128  theMedian[index] = (theMaxPix[index] + theMinPix[index])/2.0;
129  }
130 }
131 
132 void ossimBandClipFilter::setMinMaxPix(const vector<double>& minPix,
133  const vector<double>& maxPix)
134 {
135  theMinPix = minPix;
136  theMaxPix = maxPix;
137 
139 }
140 
141 const std::vector<double>& ossimBandClipFilter::getMinPixList()const
142 {
143  return theMinPix;
144 }
145 
146 const std::vector<double> ossimBandClipFilter::getMaxPixList()const
147 {
148  return theMaxPix;
149 }
150 
152 {
153  return index<theMinPix.size()?theMinPix[index]:0;
154 }
155 
157 {
158  return index<theMaxPix.size()?theMaxPix[index]:0;
159 }
160 
162  const ossimIrect& rect,
163  ossim_uint32 resLevel)
164 {
165  if(!theInputConnection)
166  {
167  return NULL;
168  }
169 
171  theInputConnection->getTile(rect, resLevel);
172  if(!data.get())
173  {
174  return data;
175  }
177  if((status != OSSIM_NULL) &&
178  (status != OSSIM_EMPTY))
179  {
180  ossim_uint32 dw = data->getWidth();
181  ossim_uint32 dh = data->getHeight();
182  ossim_uint32 db = data->getNumberOfBands();
183 
184  ossim_uint32 tw = theTile->getWidth();
187 
188  if(((tw*th)!=(dw*dh))||
189  (tb != db))
190  {
191  theTile = new ossimImageData(this,
193  db,
194  dw,
195  dh);
196  theTile->initialize();
197  }
198 
200  {
201  // Should this go on??? (drb)
203  << "ossimBandClipFilter::getTile\n"
204  << "getNumberOfValues() != theTile->getNumberOfBands"
205  << endl;
206  }
207 
208  data->copyTileToNormalizedBuffer(static_cast<float*>(theTile->getBuf()));
210 
211  switch(theClipType)
212  {
214  {
215  runClip();
216  break;
217  }
219  {
220  runClamp();
221  break;
222  }
224  {
226  break;
227  }
229  {
231  break;
232  }
233  default:
234  break;
235  }
236  data->copyNormalizedBufferToTile(static_cast<float*>(theTile->getBuf()));
237  }
238 
239  return data;
240 }
241 
243 {
244  ossim_uint32 offset = 0;
245  ossim_uint32 upperBound = theTile->getWidth()*theTile->getHeight();
246  for(ossim_uint32 band =0; band < theTile->getNumberOfBands(); ++band)
247  {
248  float *buf = static_cast<float*>(theTile->getBuf(band));
249  float minPix = theMinPix[band];
250  float maxPix = theMaxPix[band];
251  float nullPix = theTile->getNullPix(band);
252 
253  if(buf)
254  {
255  for(offset = 0; offset < upperBound; ++offset)
256  {
257  if((*buf < minPix)||
258  (*buf > maxPix))
259  {
260  *buf = nullPix;
261  }
262  ++buf;
263  }
264  }
265  }
266  theTile->validate();
267 }
268 
270 {
271  ossim_uint32 offset = 0;
272  ossim_uint32 upperBound = theTile->getWidth()*theTile->getHeight();
273  for(ossim_uint32 band =0; band < theTile->getNumberOfBands(); ++band)
274  {
275  float *buf = static_cast<float*>(theTile->getBuf(band));
276  float minPix = theMinPix[band];
277  float maxPix = theMaxPix[band];
278  float nullPix = theTile->getNullPix(band);
279 
280  if(buf)
281  {
283  {
284  for(offset = 0; offset < upperBound; ++offset)
285  {
286  if(*buf != nullPix)
287  {
288  if(*buf < minPix)
289  {
290  *buf = minPix;
291  }
292  else if(*buf > maxPix)
293  {
294  *buf = maxPix;
295  }
296  }
297  ++buf;
298  }
299  }
300  else
301  {
302  for(offset = 0; offset < upperBound; ++offset)
303  {
304  if(*buf < minPix)
305  {
306  *buf = minPix;
307  }
308  else if(*buf > maxPix)
309  {
310  *buf = maxPix;
311  }
312  ++buf;
313  }
314  }
315  }
316  }
317 }
318 
320 {
324  ossim_uint32 upperBound = w*h;
325  const double* minPixArray = theTile->getMinPix();
326  const double* maxPixArray = theTile->getMaxPix();
327 
328  float* *bandArray = new float*[bands];
329  ossim_uint32 band = 0;
330  for(band = 0; band < bands; ++band)
331  {
332  bandArray[band] = static_cast<float*>(theTile->getBuf(band));
333  }
334 
336  {
337  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
338  {
339  if(!theTile->isNull(offset))
340  {
341  for(band = 0; band < bands; ++band)
342  {
343  double delta = theMaxPix[band] - theMinPix[band];
344  double t = (bandArray[band][offset] - theMinPix[band])/delta;
345  if(t < 0)
346  {
347  bandArray[band][offset] = minPixArray[band];
348  }
349  else if(t > 1)
350  {
351  bandArray[band][offset] = maxPixArray[band];
352  }
353  else
354  {
355  bandArray[band][offset] = t;
356  }
357  }
358  }
359  }
360  }
361  else if(theTile->getDataObjectStatus() == OSSIM_FULL)
362  {
363  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
364  {
365  for(band = 0; band < bands; ++band)
366  {
367  double delta = theMaxPix[band] - theMinPix[band];
368  double t = (bandArray[band][offset] - theMinPix[band])/delta;
369 
370  if(t < 0)
371  {
372  bandArray[band][offset] = minPixArray[band];
373  }
374  else if(t > 1)
375  {
376  bandArray[band][offset] = maxPixArray[band];
377  }
378  else
379  {
380  bandArray[band][offset] = t;
381  }
382  }
383  }
384  }
385  delete [] bandArray;
386 
387 }
388 
390 {
392  float* *bandArray = new float*[bands];
393  ossim_uint32 band = 0;
394 
395  for(band = 0; band < bands; ++band)
396  {
397  bandArray[band] = static_cast<float*>(theTile->getBuf(band));
398  }
399  ossim_uint32 upperBound = theTile->getWidth()*theTile->getHeight();
400 
402  {
403  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
404  {
405  if(!theTile->isNull(offset))
406  {
407  for(band = 0; band < bands; ++band)
408  {
409  double side = (theMedian[band] - (double)bandArray[band][offset]);
410 
411  if(side > 0) // on the left
412  {
413  double delta = fabs(theMedian[band] - theMinPix[band]);
414  double t = ((double)bandArray[band][offset] - theMinPix[band])/delta;
415  if(t < 0)
416  {
417  bandArray[band][offset] = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
418  }
419  else if(t > 1)
420  {
421  bandArray[band][offset] = theMedian[band];
422  }
423  else
424  {
425  bandArray[band][offset] = theMedian[band]*t;
426  }
427  }
428  else // on the right
429  {
430  double delta = theMaxPix[band] - theMedian[band];
431  double t = ((double)bandArray[band][offset] - theMedian[band])/delta;
432 
433  if(t < 0)
434  {
435  bandArray[band][offset] = theMedian[band];
436  }
437  else if(t > 1)
438  {
439  bandArray[band][offset] = OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT;
440  }
441  else
442  {
443  bandArray[band][offset] = theMedian[band]+delta*t;
444  }
445  }
446  }
447  }
448  }
449  }
450  else if(theTile->getDataObjectStatus() == OSSIM_FULL)
451  {
452  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
453  {
454  for(band = 0; band < bands; ++band)
455  {
456  double side = (theMedian[band] - (double)bandArray[band][offset]);
457 
458  if(side > 0) // on the left
459  {
460  double delta = fabs(theMedian[band] - theMinPix[band]);
461  double t = ((double)bandArray[band][offset] - theMinPix[band])/delta;
462  if(t < 0)
463  {
464  bandArray[band][offset] = OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT;
465  }
466  else if(t > 1)
467  {
468  bandArray[band][offset] = theMedian[band];
469  }
470  else
471  {
472  bandArray[band][offset] = theMedian[band]*t;
473  }
474  }
475  else // on the right
476  {
477  double delta = theMaxPix[band] - theMedian[band];
478  double t = ((double)bandArray[band][offset] - theMedian[band])/delta;
479 
480  if(t < 0)
481  {
482  bandArray[band][offset] = theMedian[band];
483  }
484  else if(t > 1)
485  {
486  bandArray[band][offset] = OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT;
487  }
488  else
489  {
490  bandArray[band][offset] = theMedian[band]+delta*t;
491  }
492  }
493  }
494  }
495  }
496 
497  delete [] bandArray;
498 }
499 
501 {
503 
505  {
507 
508  if(bands)
509  {
510  if(theMinPix.size() != bands)
511  {
512  setNumberOfValues(bands);
513  }
514  }
515  }
516 }
517 
519  const char* prefix)
520 {
521  bool result = ossimImageSourceFilter::loadState(kwl, prefix);
522 
523  if(result)
524  {
525  ossimString minRegExpression = ossimString("^(") +
526  ossimString(prefix) +
527  "min[0-9]+)";
528  ossimString maxRegExpression = ossimString("^(") +
529  ossimString(prefix) +
530  "max[0-9]+)";
531  ossimString medianRegExpression = ossimString("^(") +
532  ossimString(prefix) +
533  "median[0-9]+)";
534 
535  ossim_uint32 numberOfMins = kwl.getNumberOfSubstringKeys(minRegExpression);
536  ossim_uint32 numberOfMaxs = kwl.getNumberOfSubstringKeys(maxRegExpression);
537  ossim_uint32 numberOfMedians = kwl.getNumberOfSubstringKeys(medianRegExpression);
538  theMinPix.clear();
539  theMaxPix.clear();
540  theMedian.clear();
541 
542  if(numberOfMins != numberOfMaxs)
543  {
544  ossim_int32 temp = (ossim_int32)min(numberOfMins, numberOfMaxs);
545  numberOfMins = temp;
546  numberOfMaxs = temp;
547  }
548  if(numberOfMins> 0)
549  {
550  ossimString prefixMin = ossimString(prefix) + "min";
551  ossimString prefixMax = ossimString(prefix) + "max";
552  ossimString prefixMedian = ossimString(prefix) + "median";
553 
554  ossim_uint32 numberOfMatches = 0;
555  ossim_uint32 index = 0;
556  const char* value=(const char*)NULL;
557 
558  while(numberOfMatches < numberOfMins)
559  {
560  value = kwl.find(prefixMin.c_str(),
561  ossimString::toString(index).c_str());
562  if(value)
563  {
564  theMinPix.push_back(ossimString(value).toDouble());
565  ++numberOfMatches;
566  }
567  ++index;
568  }
569  index = 0;
570  numberOfMatches = 0;
571  while(numberOfMatches < numberOfMaxs)
572  {
573  value = kwl.find(prefixMax.c_str(),
574  ossimString::toString(index).c_str());
575  if(value)
576  {
577  theMaxPix.push_back(ossimString(value).toDouble());
578  ++numberOfMatches;
579  }
580  ++index;
581  }
582  if(numberOfMedians != numberOfMins)
583  {
584  for(index = 0; index < theMaxPix.size(); ++index)
585  {
586  theMedian.push_back((theMinPix[index]+theMaxPix[index])/2.0);
587  }
588  }
589  else
590  {
591  index = 0;
592  numberOfMatches = 0;
593  while(numberOfMatches < numberOfMedians)
594  {
595  value = kwl.find(prefixMedian.c_str(),
596  ossimString::toString(index).c_str());
597  if(value)
598  {
599  theMedian.push_back(ossimString(value).toDouble());
600  ++numberOfMatches;
601  }
602  ++index;
603  }
604  }
605  }
606  }
607  const char* clip_type = kwl.find(prefix, "clip_type");
608  if(clip_type)
609  {
610  ossimString clipType = clip_type;
611  clipType = clipType.upcase().trim();
612 
613  if(clipType == "NONE")
614  {
616  }
617  else if(clipType == "CLIP")
618  {
620  }
621  else if(clipType == "LINEAR_STRETCH")
622  {
624  }
625  else if(clipType == "MEDIAN_STRETCH")
626  {
628  }
629  }
630  else
631  {
633  << "ossimBandClipFilter::loadState NOTICE:\n"
634  << "Clip type not given defaulting to NONE" << endl;
636  }
637 
638  return result;
639 }
640 
642  const char* prefix)const
643 {
644  ossimString minPrefix = ossimString("min");
645  ossimString maxPrefix = ossimString("max");
646  ossimString medianPrefix = ossimString("median");
647 
648  for(ossim_uint32 index = 1; index <= getNumberOfValues(); ++index)
649  {
650  ossimString value = (minPrefix+ossimString::toString(index));
651  kwl.add(prefix,
652  value.c_str(),
653  theMinPix[index-1],
654  true);
655  value = (maxPrefix+ossimString::toString(index));
656  kwl.add(prefix,
657  value.c_str(),
658  theMaxPix[index-1],
659  true);
660  value = (medianPrefix+ossimString::toString(index));
661  kwl.add(prefix,
662  value.c_str(),
663  theMedian[index-1],
664  true);
665  }
666  ossimString clipType;
667  switch(theClipType)
668  {
670  {
671  clipType = "NONE";
672  break;
673  }
675  {
676  clipType = "CLIP";
677  break;
678  }
680  {
681  clipType = "LINEAR_STRETCH";
682  break;
683  }
685  {
686  clipType = "MEDIAN_STRETCH";
687  break;
688  }
689  default:
690  break;
691  }
692  kwl.add(prefix,
693  "clip_type",
694  clipType.c_str(),
695  true);
696 
697  return ossimImageSourceFilter::saveState(kwl, prefix);
698 }
virtual ossim_uint32 getWidth() const
RTTI_DEF1(ossimBandClipFilter, "ossimBandClipFilter", ossimImageSourceFilter)
virtual const ossim_float64 * getMaxPix() const
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
virtual ossim_uint32 getNumberOfBands() const
ossim_uint32 getNumberOfSubstringKeys(const ossimString &regularExpression) const
void setMinMaxPix(const vector< double > &minPix, const vector< double > &maxPix)
ossimRefPtr< ossimImageData > getTile(const ossimIrect &rect, ossim_uint32 resLevel=0)
ossimRefPtr< ossimImageData > theTile
Represents serializable keyword/value map.
std::vector< double > theMaxPix
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
const char * find(const char *key) const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=NULL)
Method to the load (recreate) the state of an object from a keyword list.
static ossimString toString(bool aValue)
Numeric to string methods.
void setClipType(ossimBandClipType clipType)
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
std::vector< double > theMedian
double getMaxPix(ossim_uint32 index) const
virtual void initialize()
Initialize the data buffer.
bool isNull(ossim_uint32 offset) const
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
std::vector< double > theMinPix
ossimBandClipType getClipType() const
yy_size_t size
virtual ossimDataObjectStatus validate() const
virtual ossim_uint32 getNumberOfValues() const
ossimImageSource * theInputConnection
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.
virtual void copyTileToNormalizedBuffer(ossim_float64 *buf) const
Copies entire tile to buf passed in.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual void copyNormalizedBufferToTile(ossim_float64 *buf)
Copies buf passed in to tile.
double getMinPix(ossim_uint32 index) const
virtual const ossim_float64 * getMinPix() const
return status
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
#define max(a, b)
Definition: auxiliary.h:76
virtual const void * getBuf() const
#define OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT
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
virtual void setDataObjectStatus(ossimDataObjectStatus status) const
Full list found in ossimConstants.h.
ossimDataObjectStatus
Definitions for data object status.
ossimBandClipType theClipType
const std::vector< double > & getMinPixList() const
#define OSSIM_DEFAULT_MAX_PIX_NORM_FLOAT
const std::vector< double > getMaxPixList() const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void setNumberOfValues(ossim_uint32 size)
#define min(a, b)
Definition: auxiliary.h:75
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=NULL) const
Method to save the state of an object to a keyword list.