OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimMaxMosaic.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2005 SANZ Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Kenneth Melero (kmelero@sanz.com)
9 //
10 // Description: This combiner is designed to "float" the maximum pixel value
11 // of all inputs to top of the mosaic output.
12 //
13 //*************************************************************************
14 // $Id: ossimMaxMosaic.cpp 23257 2015-04-13 16:57:14Z dburken $
15 
19 #include <ossim/base/ossimTrace.h>
20 
21 static const ossimTrace traceDebug("ossimMaxMosaic:debug");
22 
23 using namespace std;
24 
28  theTile(NULL)
29 {
30 }
31 
33  : ossimImageCombiner(inputSources),
34  theTile(NULL)
35 {
36 }
37 
38 
40 {
41 }
42 
44  const ossimIrect& tileRect,
45  ossim_uint32 resLevel)
46 {
47  long size = getNumberOfInputs();
48  ossim_uint32 layerIdx = 0;
49  // If there is only one in the mosaic then just return it.
50  if(size == 1)
51  {
52  return getNextTile(layerIdx, 0, tileRect, resLevel);
53  }
54 
55  ossimIpt origin = tileRect.ul();
56  ossim_uint32 w = tileRect.width();
57  ossim_uint32 h = tileRect.height();
58 
59  if(!theTile.valid())
60  {
61  // First time through...
62  allocate();
63 
64  // If we still don't have a buffer then we will leave.
65  if(!theTile.valid())
66  {
68  }
69  }
70 
71  ossim_uint32 tileW = theTile->getWidth();
72  ossim_uint32 tileH = theTile->getHeight();
73  if((w != tileW)||
74  (h != tileH))
75  {
76  theTile->setWidth(w);
77  theTile->setHeight(h);
78  if((w*h)!=(tileW*tileH))
79  {
81  }
82  }
83  theTile->setOrigin(origin);
84 
85  //---
86  // General Note:
87  //
88  // Note: I will not check for disabled or enabled since we have
89  // no clear way to handle this within a mosaic. The default will be
90  // to do a simple a A over B type mosaic. Derived classes should
91  // check for the enabled and disabled and always
92  // use this default implementation if they are disabled.
93  //---
94  theTile->setOrigin(origin);
95  theTile->makeBlank();
96  switch(theTile->getScalarType())
97  {
98  case OSSIM_UCHAR:
99  {
100  if(!hasDifferentInputs())
101  {
102  return combine(static_cast<ossim_uint8>(0),
103  tileRect,
104  resLevel);
105  }
106  else
107  {
108  return combineNorm(static_cast<ossim_uint8>(0),
109  tileRect,
110  resLevel);
111  }
112  }
113  case OSSIM_SINT8:
114  {
115  if(!hasDifferentInputs())
116  {
117  return combine(static_cast<ossim_sint8>(0),
118  tileRect,
119  resLevel);
120  }
121  else
122  {
123  return combineNorm(static_cast<ossim_sint8>(0),
124  tileRect,
125  resLevel);
126  }
127  }
128  case OSSIM_FLOAT:
130  {
131  if(!hasDifferentInputs())
132  {
133  return combine(static_cast<float>(0),
134  tileRect,
135  resLevel);
136  }
137  else
138  {
139  return combineNorm(static_cast<float>(0),
140  tileRect,
141  resLevel);
142  }
143  }
144  case OSSIM_USHORT16:
145  case OSSIM_USHORT11:
146  case OSSIM_USHORT12:
147  case OSSIM_USHORT13:
148  case OSSIM_USHORT14:
149  case OSSIM_USHORT15:
150  {
151  if(!hasDifferentInputs())
152  {
153  return combine(static_cast<ossim_uint16>(0),
154  tileRect,
155  resLevel);
156  }
157  else
158  {
159  return combineNorm(static_cast<ossim_uint16>(0),
160  tileRect,
161  resLevel);
162  }
163  }
164  case OSSIM_SSHORT16:
165  {
166  if(!hasDifferentInputs())
167  {
168  return combine(static_cast<ossim_sint16>(0),
169  tileRect,
170  resLevel);
171  }
172  else
173  {
174  return combineNorm(static_cast<ossim_sint16>(0),
175  tileRect,
176  resLevel);
177  }
178  }
179  case OSSIM_SINT32:
180  {
181  if(!hasDifferentInputs())
182  {
183  return combine(static_cast<ossim_sint32>(0),
184  tileRect,
185  resLevel);
186  }
187  else
188  {
189  return combineNorm(static_cast<ossim_sint32>(0),
190  tileRect,
191  resLevel);
192  }
193  }
194  case OSSIM_UINT32:
195  {
196  if(!hasDifferentInputs())
197  {
198  return combine(static_cast<ossim_uint32>(0),
199  tileRect,
200  resLevel);
201  }
202  else
203  {
204  return combineNorm(static_cast<ossim_uint32>(0),
205  tileRect,
206  resLevel);
207  }
208  }
209  case OSSIM_DOUBLE:
211  {
212  if(!hasDifferentInputs())
213  {
214  return combine(static_cast<double>(0),
215  tileRect,
216  resLevel);
217  }
218  else
219  {
220  return combineNorm(static_cast<double>(0),
221  tileRect,
222  resLevel);
223  }
224  }
226  default:
227  {
229  << "Scalar type = " << theTile->getScalarType()
230  << " Not supported by ossimMaxMosaic" << endl;
231  }
232  }
233 
235 }
236 
238 {
240  theTile = NULL;
241 }
242 
244 {
245  theTile = NULL;
246 
247  if( (getNumberOfInputs() > 0) && getInput(0) )
248  {
250  theTile->initialize();
251  }
252 }
253 
255  const char* prefix)const
256 {
257  return ossimImageCombiner::saveState(kwl, prefix);
258 }
259 
261  const char* prefix)
262 {
263  return ossimImageCombiner::loadState(kwl, prefix);
264 }
265 
267  T,// dummy template variable
268  const ossimIrect& tileRect,
269  ossim_uint32 resLevel)
270 {
271  ossim_uint32 layerIdx = 0;
272  ossimRefPtr<ossimImageData> destination = theTile;
273 
274  ossimRefPtr<ossimImageData> currentImageData =
275  getNextNormTile(layerIdx, 0, tileRect, resLevel);
276 
277  if(!currentImageData)
278  {
279  return currentImageData;
280  }
281 
282  std::vector<float*> srcBands(theLargestNumberOfInputBands);
283  std::vector<float> srcBandsNullPix(theLargestNumberOfInputBands);
284  std::vector<T*> destBands(theLargestNumberOfInputBands);
285  std::vector<T> destBandsNullPix(theLargestNumberOfInputBands);
286  std::vector<T> destBandsMinPix(theLargestNumberOfInputBands);
287  std::vector<T> destBandsMaxPix(theLargestNumberOfInputBands);
288  //float** srcBands = new float*[theLargestNumberOfInputBands];
289  //float* srcBandsNullPix = new float[theLargestNumberOfInputBands];
290  //T** destBands = new T*[theLargestNumberOfInputBands];
291  //T* destBandsNullPix = new T[theLargestNumberOfInputBands];
292  //T* destBandsMinPix = new T[theLargestNumberOfInputBands];
293  //T* destBandsMaxPix = new T[theLargestNumberOfInputBands];
294 
295  ossim_uint32 band;
296  ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
297  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
298  for(band = 0; band < minNumberOfBands; ++band)
299  {
300  srcBands[band] = static_cast<float*>(currentImageData->getBuf(band));
301  srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(band));
302 
303  destBands[band] = static_cast<T*>(theTile->getBuf(band));
304  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
305  destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
306  destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
307  }
308  // if the src is smaller than the destination in number
309  // of bands we will just duplicate the last band.
310  for(;band < theLargestNumberOfInputBands; ++band)
311  {
312  srcBands[band] = static_cast<float*>(srcBands[minNumberOfBands - 1]);
313  srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(minNumberOfBands - 1));
314 
315  destBands[band] = static_cast<T*>(theTile->getBuf(band));
316  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
317  destBandsMinPix[band] = static_cast<T>(theTile->getMinPix(band));
318  destBandsMaxPix[band] = static_cast<T>(theTile->getMaxPix(band));
319  }
320  // most of the time we will not overlap so let's
321  // copy the first tile into destination and check later.
322  //
323  ossim_uint32 tempBandIdx = 0;
324  for(band = 0; band < theTile->getNumberOfBands();++band)
325  {
326  if(band < currentImageData->getNumberOfBands())
327  {
329  (float*)currentImageData->getBuf(band));
330  ++tempBandIdx;
331  }
332  else
333  {
334  if(tempBandIdx)
335  {
337  (float*)currentImageData->getBuf(tempBandIdx-1));
338  }
339  }
340  }
341  destination->validate();
342 
343  currentImageData = getNextNormTile(layerIdx, tileRect, resLevel);
344 
345  while(currentImageData.valid())
346  {
347  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
348  ossimDataObjectStatus currentStatus = currentImageData->getDataObjectStatus();
349  ossimDataObjectStatus destinationStatus = destination->getDataObjectStatus();
350 
351  if(destinationStatus == OSSIM_FULL)
352  {
353  return destination;
354  }
355  for(band = 0; band < minNumberOfBands; ++band)
356  {
357  srcBands[band] = static_cast<float*>(currentImageData->getBuf(band));
358  srcBandsNullPix[band] = static_cast<float>(currentImageData->getNullPix(band));
359  }
360  // if the src is smaller than the destination in number
361  // of bands we will just duplicate the last band.
362  for(;band < theLargestNumberOfInputBands; ++band)
363  {
364  srcBands[band] = srcBands[minNumberOfBands - 1];
365  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
366  }
367 
368  if((destinationStatus == OSSIM_EMPTY)&&
369  (currentStatus != OSSIM_EMPTY)&&
370  (currentStatus != OSSIM_NULL))
371  {
372  ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
373  for(band=0; band < theLargestNumberOfInputBands; ++band)
374  {
375  float delta = destBandsMaxPix[band] - destBandsMinPix[band];
376  float minP = destBandsMinPix[band];
377  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
378  {
379  destBands[band][offset] = (T)( minP + delta*srcBands[band][offset]);
380  }
381  }
382  }
383  else if((destinationStatus == OSSIM_PARTIAL)&&
384  (currentStatus != OSSIM_EMPTY)&&
385  (currentStatus != OSSIM_NULL))
386  {
387  for(band = 0; band < theLargestNumberOfInputBands; ++band)
388  {
389 
390  float delta = destBandsMaxPix[band] - destBandsMinPix[band];
391  float minP = destBandsMinPix[band];
392  for(ossim_uint32 offset = 0;
393  offset < upperBound;
394  ++offset)
395  {
396 
397  if(destBands[band][offset] == destBandsNullPix[band])
398  {
399  destBands[band][offset] = (T)(minP + delta*srcBands[band][offset]);
400  }
401  }
402  }
403  }
404  destination->validate();
405 
406  currentImageData = getNextNormTile(layerIdx, tileRect, resLevel);
407  }
408  // Cleanup...
409  // delete [] srcBands;
410  // delete [] srcBandsNullPix;
411  // delete [] destBands;
412  // delete [] destBandsNullPix;
413  // delete [] destBandsMinPix;
414  // delete [] destBandsMaxPix;
415 
416  return destination;
417 }
418 
420  T,// dummy template variable
421  const ossimIrect& tileRect,
422  ossim_uint32 resLevel)
423 {
424  ossim_uint32 layerIdx = 0;
425  ossimRefPtr<ossimImageData> destination = theTile;
426 
427  ossimRefPtr<ossimImageData> currentImageData = getNextTile(layerIdx, 0, tileRect, resLevel);
428  if(!currentImageData)
429  {
430  return currentImageData;
431  }
432 
433  T** srcBands = new T*[theLargestNumberOfInputBands];
434  T* srcBandsNullPix = new T[theLargestNumberOfInputBands];
435  T** destBands = new T*[theLargestNumberOfInputBands];
436  T* destBandsNullPix = new T[theLargestNumberOfInputBands];
437 
438  ossim_uint32 band;
439  ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
440  ossim_uint32 bandIndex = 0;
441 
442  ossim_uint32 offset=0;
443  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
444  for(band = 0; band < minNumberOfBands; ++band)
445  {
446  srcBands[band] = static_cast<T*>(currentImageData->getBuf(band));
447  destBands[band] = static_cast<T*>(theTile->getBuf(band));
448  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(band));
449  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
450  }
451  // if the src is smaller than the destination in number
452  // of bands we will just duplicate the last band.
453  for(;band < theLargestNumberOfInputBands; ++band)
454  {
455  srcBands[band] = static_cast<T*>(srcBands[minNumberOfBands - 1]);
456  destBands[band] = static_cast<T*>(theTile->getBuf(band));
457  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
458  destBandsNullPix[band] = static_cast<T>(theTile->getNullPix(band));
459  }
460  // most of the time we will not overlap so let's
461  // copy the first tile into destination and check later.
462  //
463  for(band = 0; band < theTile->getNumberOfBands();++band)
464  {
465  T* destBand = destBands[band];
466  T* srcBand = srcBands[band];
467  if(destBand&&srcBand)
468  {
469  for(offset = 0; offset < upperBound;++offset)
470  {
471  *destBand = *srcBand;
472  ++srcBand; ++destBand;
473  }
474  }
475  }
476  destination->setDataObjectStatus(currentImageData->getDataObjectStatus());
477 
478  currentImageData = getNextTile(layerIdx,
479  tileRect,
480  resLevel);
481 
482  while(currentImageData.valid())
483  {
484  ossim_uint32 minNumberOfBands = currentImageData->getNumberOfBands();
485  ossimDataObjectStatus currentStatus = currentImageData->getDataObjectStatus();
486  ossimDataObjectStatus destinationStatus = destination->getDataObjectStatus();
487 
488  for(band = 0; band < minNumberOfBands; ++band)
489  {
490  srcBands[band] = static_cast<T*>(currentImageData->getBuf(band));
491  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(band));
492  }
493  // if the src is smaller than the destination in number
494  // of bands we will just duplicate the last band.
495  for(;band < theLargestNumberOfInputBands; ++band)
496  {
497  srcBands[band] = srcBands[minNumberOfBands - 1];
498  srcBandsNullPix[band] = static_cast<T>(currentImageData->getNullPix(minNumberOfBands - 1));
499  }
500 
501  if((destinationStatus == OSSIM_PARTIAL)&&
502  (currentStatus != OSSIM_EMPTY)&&
503  (currentStatus != OSSIM_NULL))
504  {
505  for(bandIndex = 0; bandIndex < theLargestNumberOfInputBands; ++bandIndex)
506  {
507 
508  for(ossim_uint32 offset = 0;
509  offset < upperBound;
510  ++offset)
511  {
512  if(srcBands[bandIndex][offset] > destBands[bandIndex][offset])
513  {
514  destBands[bandIndex][offset] = srcBands[bandIndex][offset];
515  }
516  }
517  }
518  }
519  else
520  {
521  ossim_uint32 upperBound = destination->getWidth()*destination->getHeight();
522  for(ossim_uint32 band=0; band < theLargestNumberOfInputBands; ++band)
523  {
524  for(ossim_uint32 offset = 0; offset < upperBound; ++offset)
525  {
526  if(srcBands[band][offset] > destBands[band][offset])
527  {
528  destBands[band][offset] = srcBands[band][offset];
529  }
530  }
531  }
532  }
533 
534  destination->validate();
535 
536  currentImageData = getNextTile(layerIdx,tileRect, resLevel);
537  }
538  // Cleanup...
539  delete [] srcBands;
540  delete [] srcBandsNullPix;
541  delete [] destBands;
542  delete [] destBandsNullPix;
543  return destination;
544 }
545 
547 {
548  return ossimString("ossimMaxMosaic");
549 }
550 
552 {
553  return ossimString("Max Mosaic");
554 }
555 
557 {
558  return ossimString("Combiner which puts maximum dn value on image.");
559 }
16 bit unsigned integer (15 bits used)
8 bit signed integer
virtual ossim_uint32 getWidth() const
virtual ossimString getLongName() const
virtual const ossim_float64 * getMaxPix() const
virtual ossim_uint32 getNumberOfBands() const
This will be a base for all combiners.
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
virtual ossimRefPtr< ossimImageData > getNextNormTile(ossim_uint32 &returnedIdx, const ossim_uint32 index, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
ossim_uint32 height() const
Definition: ossimIrect.h:487
virtual void initialize()
const ossimIpt & ul() const
Definition: ossimIrect.h:274
virtual ossimDataObjectStatus getDataObjectStatus() const
virtual ossim_uint32 getHeight() const
16 bit unsigned integer (14 bits used)
16 bit unsigned integer (13 bits used)
32 bit unsigned integer
virtual void initialize()
Initialize the data buffer.
void allocate()
Called on first getTile, will initialize all data needed.
ossimConnectableObject * getInput(ossim_uint32 index=0)
returns the object at the specified index.
ossimRefPtr< ossimImageData > combine(T, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
virtual void setHeight(ossim_uint32 height)
virtual ossimRefPtr< ossimImageData > getNextTile(ossim_uint32 &returnedIdx, const ossim_uint32 startIdx, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
std::vector< ossimRefPtr< ossimConnectableObject > > ConnectableObjectList
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &origin, ossim_uint32 resLevel=0)
static ossimImageDataFactory * instance()
virtual ossimString getDescription() const
ossim_uint32 theLargestNumberOfInputBands
yy_size_t size
virtual ossimDataObjectStatus validate() const
32 bit signed integer
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
32 bit normalized floating point
virtual void setWidth(ossim_uint32 width)
virtual ~ossimMaxMosaic()
virtual void copyNormalizedBufferToTile(ossim_float64 *buf)
Copies buf passed in to tile.
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
virtual bool hasDifferentInputs() const
virtual void setOrigin(const ossimIpt &origin)
virtual const ossim_float64 * getMinPix() const
virtual ossimScalarType getScalarType() const
virtual void makeBlank()
Initializes data to null pixel values.
64 bit normalized floating point
16 bit unsigned integer (11 bits used)
ossimRefPtr< ossimImageData > combineNorm(T, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
ossimRefPtr< ossimImageData > theTile
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
virtual const void * getBuf() const
virtual ossim_uint32 getNumberOfInputs() const
Returns the number of input objects.
virtual void setDataObjectStatus(ossimDataObjectStatus status) const
Full list found in ossimConstants.h.
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=NULL)
Method to the load (recreate) the state of an object from a keyword list.
ossimDataObjectStatus
Definitions for data object status.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=NULL) const
Method to save the state of an object to a keyword list.
32 bit floating point
virtual ossimString getShortName() const
16 bit unsigned iteger
64 bit floating point
16 bit signed integer
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
An image mosaic is a simple combiner that will just do a simple mosaic.
8 bit unsigned iteger
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
16 bit unsigned integer (12 bits used)