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