OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGammaRemapper.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2002 ImageLinks Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Kathy Minear
9 //
10 // Description: Takes in DNs for any number of bands
11 // Converts DNs to Radiance at the satellite values Lsat
12 // Converts Lsat to Surface Reflectance values
13 //
14 //*************************************************************************
15 // $Id: ossimGammaRemapper.cpp 12980 2008-06-04 00:50:33Z dburken $
16 
17 #include <cstdlib>
18 #include <cmath>
19 
22 #include <ossim/base/ossimTrace.h>
27 
28 
30 
31 static const double DEFAULT_GAMMA = 1.0;
32 
33 
34 static ossimTrace traceDebug("ossimGammaRemapper:debug");
35 
37  :
38  ossimImageSourceFilter (owner), // base class
39  theTile (NULL),
40  theBuffer (NULL),
41  theMinPixelValue (0),
42  theMaxPixelValue (0),
43  theGamma (0),
44  theUserDisabledFlag (false)
45 {
46  //***
47  // Set the base class "theEnableFlag" to off since no adjustments have been
48  // made yet.
49  //***
50  disableSource();
51 
52  // Construction not complete.
53 }
54 
55 
57  :
58  ossimImageSourceFilter (NULL, inputSource), // base class
59  theTile (NULL),
60  theBuffer (NULL),
61  theMinPixelValue (0),
62  theMaxPixelValue (0),
63  theGamma (0),
64  theUserDisabledFlag (false)
65 {
66  //***
67  // Set the base class "theEnableFlag" to off since no adjustments have been
68  // made yet.
69  //***
70  disableSource();
71 
72  if (inputSource == NULL)
73  {
75  cerr << "ossimGammaRemapper::ossimGammaRemapper ERROR:"
76  << "\nNull input source passed to constructor!" << endl;
77  return;
78  }
79 
80  initialize();
81 }
82 
83 
85  ossimImageSource* inputSource)
86  :
87  ossimImageSourceFilter (owner, inputSource), // base class
88  theTile (NULL),
89  theBuffer (NULL),
90  theMinPixelValue (0),
91  theMaxPixelValue (0),
92  theGamma (0)
93 {
94  //***
95  // Set the base class "theEnableFlag" to off since no adjustments have been
96  // made yet.
97  //***
98  disableSource();
99 
100  if (inputSource == NULL)
101  {
102  setErrorStatus();
103  cerr << "ossimGammaRemapper::ossimGammaRemapper ERROR:"
104  << "\nNull input source passed to constructor!" << endl;
105  return;
106  }
107 
108  initialize();
109 }
110 
112 {
113  if (theBuffer)
114  {
115  delete [] theBuffer;
116  theBuffer = NULL;
117  }
118 }
119 
121  ossim_uint32 resLevel)
122 {
123  if (!isInitialized())
124  {
125  cerr << "ossimGammaRemapper::getTile ERROR:"
126  << "\nNot initialized!"
127  << endl;
129  }
130 
131  // Fetch tile from pointer from the input source.
133  tile_rect, resLevel);
134 
135  if (!inputTile.valid()) // Just in case...
136  {
137  cerr << "ossimGammaRemapper::getTile ERROR:"
138  << "\nReceived null pointer to tile from input source!"
139  << "\nReturning blank tile."
140  << endl;
141  theTile->makeBlank();
142  return theTile;
143  }
144 
145  // Get its status.
146  ossimDataObjectStatus tile_status = inputTile->getDataObjectStatus();
147 
148  //---
149  // Check for remap bypass:
150  //---
151  if (!theEnableFlag || tile_status == OSSIM_NULL ||!theTile.valid() ||
152  tile_status == OSSIM_EMPTY)
153  {
154  return inputTile;
155  }
156 
157  ossim_uint32 w = tile_rect.width();
158  ossim_uint32 h = tile_rect.height();
159  ossim_uint32 tw = theTile->getWidth();
162 
163  // Set the origin of the output tile.
164  theTile->setOrigin(tile_rect.ul());
165 
166  if(w*h != tw*th)
167  {
168  theTile->setWidthHeight(w, h);
169  theTile->initialize();
170  if(theBuffer)
171  {
172  delete [] theBuffer;
173  theBuffer = NULL;
174  }
175  }
176 
177  if(!theBuffer)
178  {
179  theBuffer = new double[w*h*bands];
180  }
181 
182  // Copy the source tile into the buffer at the same time normalizing it.
184 
185  // for each band, get the radiance value
186 
187  ossim_uint32 buffer_index = 0;
188  const double MP = theTile->getMinNormalizedPix(); // Minimum normalized pix.
189  const ossim_uint32 PPTB = theTile->getSizePerBand(); // Pixels Per Tile Band
190 
191  for (ossim_uint32 band=0; band<bands; ++band)
192  {
193  for (ossim_uint32 i=0; i<PPTB; ++i)
194  {
195  double p = theBuffer[buffer_index]; // input pixel
196  // double p = getPix(buffer_index);
197 
198  if (p)
199  {
200  // cout<<"p before: "<<p<<endl;
201  // Stretch it...
202  p = (p - theMinPixelValue[band]) /
203  (theMaxPixelValue[band] -
204  theMinPixelValue[band]);
205 
206  p = pow(p, theGamma[band]);
207 
208 
209  //***
210  // Since it wasn't null to start with clip / clamp between minimum
211  // normalized pixel and one(max).
212  //***
213  p = ( p > MP ? ( p < 1.0 ? p : 1.0) : MP );
214 
215  theBuffer[buffer_index] = p;
216  }
217  else
218  {
219  theBuffer[buffer_index] = 0.0;
220  }
221 
222  ++buffer_index;
223  }
224  }
225 
226  // Copy the buffer to the output tile at the same time unnormalizing it.
228 
229  // Set the status to that of the input tile.
230  theTile->setDataObjectStatus(tile_status);
231 
232  return theTile;
233 }
234 
236 {
238  {
241  theTile->initialize();
242 
243  if(theBuffer)
244  {
245  delete []theBuffer;
246  theBuffer = NULL;
247  }
248 
249  ossim_uint32 tw = theTile->getWidth();
252 
253  theBuffer = new double[tw*th*bands];
254  memset(theBuffer, '\0', tw*th*bands);
255 
256  setInitializedFlag(true);
258  }
259  else
260  {
261  setInitializedFlag(false);
262  setErrorStatus();
263  cerr << "ossimGammaRemapper::initialize ERROR:"
264  << "\nCannot call method when input connection is NULL!"
265  << endl;
266  };
267 
268  verifyEnabled();
269 }
270 
271 void ossimGammaRemapper::setMinMaxPixelValues(const vector<double>& v_min,
272  const vector<double>& v_max)
273 {
274  theMinPixelValue = v_min;
275  theMaxPixelValue = v_max;
276  verifyEnabled();
277 }
278 
280 {
281  // Check all the pointers...
282  if ( !theInputConnection || !theTile || !theBuffer )
283  {
284  disableSource();
285  return;
286  }
287 
289  if ( (theMinPixelValue.size() != bands) ||
290  (theMaxPixelValue.size() != bands) )
291  {
292  disableSource();
293  return;
294  }
295 
296  if (theUserDisabledFlag == false)
297  {
298  enableSource();
299  }
300 
301  if (traceDebug())
302  {
303  cout << *this << endl;
304  }
305 }
306 
308  const char* prefix)
309 {
310  //***
311  // Call the base class to pick up the enable flag. Note that the
312  // verifyEnabled flag can override this.
313  //***
314  ossimString pref;
315  if (prefix) pref += prefix;
316  pref += "gamma_remapper.";
317 
318  if (!theTile)
319  {
320  cerr << "ossimGammaRemapper::loadState: ERROR"
321  << "Not initialized yet!" << endl;
322  return false;
323  }
324 
325  //---
326  // NOTE:
327  // base class seems to call initialize which in turn errors if you don't
328  // have a connection yet, so check for the enable keyword here...
329  // ossimSource::loadState(kwl, pref.c_str());
330  //---
331  cout << "pref: " << pref
332  << "kw: " << ossimKeywordNames::ENABLED_KW << endl;
333 
334  const char* lookup = kwl.find(pref, ossimKeywordNames::ENABLED_KW);
335  if(lookup)
336  {
337  theEnableFlag = ossimString(lookup).toBool();
338  if (theEnableFlag == false)
339  {
340  // User want filter disabled...
341  theUserDisabledFlag = true;
342  }
343  }
344 
346 
347  theGamma.clear();
348  theGamma.resize(bands, 1.0);
349 
350  for(ossim_uint32 band = 0; band < bands; ++band)
351  {
352  ossimString band_string = ".band";
353  band_string += ossimString::toString(band+1); // Start at one.
354 
355  ossimString kw = GAMMA_REMAPPER_GAMMA_KW;
356  kw += band_string;
357  lookup = kwl.find(prefix, kw.c_str());
358  if (lookup)
359  {
360  theGamma[band] = atof(lookup);
361  }
362  else
363  {
364  cout << "MODULE NOTICE:"
365  << "\nlookup failed for keyword: " << kw.c_str()
366  << "\nGamma set to " << DEFAULT_GAMMA << " for band: "
367  << (band+1) << endl;
368  theGamma[band] = DEFAULT_GAMMA;
369  }
370  }
371 
372  if (traceDebug())
373  {
374  cout << "ossimGammaRemapper DEBUG:"
375  << *this
376  << endl;
377  }
378 
379  return true;
380 }
381 
383 {
384  os << setprecision(15) << setiosflags(ios::fixed)
385  << "ossimGammaRemapper:"
386  << "\ntheEnableFlag: " << (theEnableFlag?"enabled":"disabled")
387  << endl;
388 
389  ossim_uint32 band = 1;
390  vector<double>::const_iterator i = theMinPixelValue.begin();
391  while (i != theMinPixelValue.end())
392  {
393  os << "band[" << band << "] min: " << (*i) << endl;
394  ++i;
395  ++band;
396  }
397 
398  band = 1;
399  i = theMaxPixelValue.begin();
400  while (i != theMaxPixelValue.end())
401  {
402  os << "band[" << band << "] max: " << (*i) << endl;
403  ++i;
404  ++band;
405  }
406 
407  band = 1;
408  i = theGamma.begin();
409  while (i != theGamma.end())
410  {
411  os << "band[" << band << "] gamma: " << (*i) << endl;
412  ++i;
413  ++band;
414  }
415 
416  return os;
417 }
418 
420 {
421  // Clear the flag...
422  theUserDisabledFlag = false;
424 }
425 
427 {
428  return ossimString("Gamma Remapper");
429 }
430 
432 {
433  return hr.print(os);
434 }
virtual ossim_uint32 getWidth() const
virtual bool isInitialized() const
virtual ossim_uint32 getNumberOfBands() const
virtual ossim_float64 getMinNormalizedPix() const
returns normalized minimum pixel value of band zero.
virtual ostream & print(ostream &os) const
Outputs theErrorStatus as an ossimErrorCode and an ossimString.
virtual void setWidthHeight(ossim_uint32 w, ossim_uint32 h)
Represents serializable keyword/value map.
bool theEnableFlag
Definition: ossimSource.h:62
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
ossim_uint32 height() const
Definition: ossimIrect.h:487
static ossimString toString(bool aValue)
Numeric to string methods.
virtual void disableSource()
Definition: ossimSource.cpp:89
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
virtual void setInitializedFlag(bool flag)
vector< double > theGamma
virtual void initialize()
Initialize the data buffer.
ossimGammaRemapper(ossimObject *owner=NULL)
static ossimImageDataFactory * instance()
vector< double > theMinPixelValue
void setMinMaxPixelValues(const vector< double > &v_min, const vector< double > &v_max)
bool toBool() const
String to numeric methods.
vector< double > theMaxPixelValue
virtual ossim_uint32 getSizePerBand() const
Returns the number of pixels in a single band in a tile.
ossimImageSource * theInputConnection
unsigned int ossim_uint32
virtual void enableSource()
ostream & operator<<(ostream &os, const ossimGammaRemapper &hr)
virtual void copyTileToNormalizedBuffer(ossim_float64 *buf) const
Copies entire tile to buf passed in.
virtual void enableSource()
Definition: ossimSource.cpp:84
virtual void copyNormalizedBufferToTile(ossim_float64 *buf)
Copies buf passed in to tile.
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tile_rect, ossim_uint32 resLevel=0)
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
static const char * ENABLED_KW
virtual void setOrigin(const ossimIpt &origin)
virtual void makeBlank()
Initializes data to null pixel values.
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.
virtual ossimString getShortName() const
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
ossimDataObjectStatus
Definitions for data object status.
ossimRefPtr< ossimImageData > theTile
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)