OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimImageCombiner.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 //*************************************************************************
8 // $Id: ossimImageCombiner.cpp 23108 2015-01-27 17:00:20Z okramer $
11 #include <ossim/base/ossimIrect.h>
13 #include <ossim/base/ossimTrace.h>
14 
15 using namespace std;
16 
18 static ossimTrace traceDebug ("ossimImageCombiner:debug");
19 
21  :ossimImageSource(NULL,
22  0,
23  0,
24  false,
25  false),
26  theLargestNumberOfInputBands(0),
27  theInputToPassThrough(0),
28  theHasDifferentInputs(false),
29  theNormTile(NULL),
30  theCurrentIndex(0)
31 {
33  // until something is set we will just set the blank tile
34  // to a 1 band unsigned char type
36 }
38  int numberOfInputs,
39  int numberOfOutputs,
40  bool inputListIsFixedFlag,
41  bool outputListIsFixedFlag)
42  :ossimImageSource(owner,
43  numberOfInputs,
44  numberOfOutputs,
45  inputListIsFixedFlag,
46  outputListIsFixedFlag),
47  theLargestNumberOfInputBands(0),
48  theInputToPassThrough(0),
49  theHasDifferentInputs(false),
50  theNormTile(NULL),
51  theCurrentIndex(0)
52 {
55 }
56 
58  :ossimImageSource(NULL,
59  (ossim_uint32)inputSources.size(),
60  0,
61  false,
62  false),
63  theLargestNumberOfInputBands(0),
64  theInputToPassThrough(0),
65  theHasDifferentInputs(false),
66  theNormTile(NULL),
67  theCurrentIndex(0)
68 {
70  for(ossim_uint32 index = 0; index < inputSources.size(); ++index)
71  {
72  connectMyInputTo(index, inputSources[index].get());
73  }
75  initialize();
76 }
77 
79 {
81 }
82 
84 {
85  static const char* MODULE = "ossimImageCombiner::getBoundingRect";
86  ossimIrect result;
88  {
90  }
91 
92  double scale = 1.0/std::pow(2.0, (double)resLevel);
93  ossimDpt scalar(scale, scale);
94  result.makeNan();
95 
96  ossim_uint32 inputIndex = 0;
97  ossimImageSource* interface;
98  for(inputIndex = 0;inputIndex < getNumberOfInputs(); ++inputIndex)
99  {
100  interface = PTR_CAST(ossimImageSource, getInput(inputIndex));
101  if(interface)
102  {
103  ossimIrect rect = theFullResBounds[inputIndex];
104  if(result.hasNans())
105  {
106  result = rect;
107  }
108  else if(!rect.hasNans())
109  {
110  if(traceDebug())
111  {
112  CLOG << "rect " << inputIndex << " = " << result << endl;
113  }
114  rect = rect*scale;
115  result = result.combine(rect);
116  }
117  }
118  }
119  if(traceDebug())
120  {
121  CLOG << "resulting bounding rect = " << result << endl;
122  }
123 
124  return result;
125 }
126 
128 {
130 }
131 
133 {
135  {
137  if(temp)
138  {
139  return temp->getOutputScalarType();
140  }
141  }
142 
143  return OSSIM_SCALAR_UNKNOWN;
144 }
145 
147 {
149  {
151  if(temp)
152  {
153  return temp->getTileWidth();
154  }
155  }
156 
157  return 1;
158 }
159 
161 {
163  {
165  if(temp)
166  {
167  return temp->getTileHeight();
168  }
169  }
170 
171  return 1;
172 }
173 
175 {
177  {
179  if(temp)
180  {
181  ossim_uint32 bands = temp->getNumberOfOutputBands();
182  if(band < bands)
183  {
184  return temp->getNullPixelValue(band);
185  }
186  else
187  {
188  return temp->getNullPixelValue(bands-1);
189  }
190  }
191  }
192 
193  return 0.0;
194 }
195 
197 {
198  const char* MODULE = "ossimImageCombiner::getMinPixelValue";
199 
200  if(!getNumberOfInputs())
201  {
202  return ossim::nan();
203  }
204  double result = 1.0/DBL_EPSILON;
205 
206  for(ossim_uint32 index = 0; index < getNumberOfInputs();++index)
207  {
209  if(input)
210  {
211  ossim_uint32 bands = input->getNumberOfOutputBands();
212  double temp = 0;
213  if(band < bands)
214  {
215  temp = input->getMinPixelValue(band);
216  }
217  else
218  {
219  temp = input->getMinPixelValue(0);
220  }
221 
222  if(temp < result)
223  {
224  result = temp;
225  }
226  }
227  }
228  if(traceDebug())
229  {
230  CLOG << "min pixel returned is = " << result;
231  }
232 
233  return result;
234 }
235 
237 {
238  const char* MODULE = "ossimImageCombiner::getMaxPixelValue";
239 
240  if(!getNumberOfInputs())
241  {
242  return ossim::nan();
243  }
244  double result = -1.0/DBL_EPSILON;
245 
246  for(ossim_uint32 idx = 0; idx < getNumberOfInputs();++idx)
247  {
249  if(input)
250  {
251  ossim_uint32 bands = input->getNumberOfOutputBands();
252  double temp = 0;
253  if(band < bands)
254  {
255  temp = input->getMaxPixelValue(band);
256  }
257  else
258  {
259  temp = input->getMaxPixelValue(0);
260  }
261  if(temp > result)
262  {
263  result = temp;
264  }
265  }
266  }
267 
268  if(traceDebug())
269  {
270  CLOG << "max pixel returned is = " << result;
271  }
272 
273  return result;
274 }
275 
277 {
278 
281 
282  // now find the largest number of bands
283  //
288  theHasDifferentInputs= false;
289  if(size > 0)
290  {
291  for(ossim_uint32 idx = 0; idx < size; ++idx)
292  {
294  if(temp)
295  {
296  ossim_uint32 numberOfBands = temp->getNumberOfOutputBands();
297  if(numberOfBands > theLargestNumberOfInputBands)
298  {
299  theLargestNumberOfInputBands = numberOfBands;
300  }
301  ossimScalarType current = temp->getOutputScalarType();
302  if(current != scalarType)
303  {
304  if(scalarType == OSSIM_SCALAR_UNKNOWN)
305  {
306  scalarType = current;
308  theInputToPassThrough = idx;
309  }
310  else
311  {
312  theHasDifferentInputs = true;
314  {
315  scalarType = current;
317  theInputToPassThrough = idx;
318  }
319  }
320  }
321  }
322  }
323  }
324 }
325 
326 bool ossimImageCombiner::loadState(const ossimKeywordlist& kwl, const char* prefix)
327 {
328  bool result = ossimImageSource::loadState(kwl, prefix);
329 
330  return result;
331 }
332 
334 {
336 }
337 
338 // ossimRefPtr<ossimImageData> ossimImageCombiner::getNextTile(ossim_uint32& returnedIdx,
339 // ossim_uint32 idx,
340 // const ossimIpt& tileRect,
341 // ossim_uint32 resLevel)
342 // {
343 // theCurrentIndex = idx;
344 // return getNextTile(returnedIdx, origin, resLevel);
345 // }
346 
347 // ossimRefPtr<ossimImageData> ossimImageCombiner::getNextTile(ossim_uint32& returnedIdx,
348 // ossim_uint32 idx,
349 // const ossimIpt& origin,
350 // ossim_uint32 resLevel)
351 // {
352 // theCurrentIndex = idx;
353 // return getNextTile(returnedIdx, origin, resLevel);
354 // }
355 
357  const ossim_uint32 startIdx,
358  const ossimIrect& tileRect,
359  ossim_uint32 resLevel)
360 {
361  theCurrentIndex = startIdx;
362  return getNextTile(returnedIdx, tileRect, resLevel);
363 }
364 
365 // ossimRefPtr<ossimImageData> ossimImageCombiner::getNextTile(ossim_uint32& returnedIdx,
366 // const ossimIpt& origin,
367 // ossim_uint32 resLevel)
368 // {
369 // ossim_int32 w = getTileWidth();
370 // ossim_int32 h = getTileHeight();
371 
372 // return getNextTile(returnedIndex,
373 // ossimIrect(origin.x,
374 // origin.y,
375 // origin.x + w-1,
376 // origin.y + h-1),
377 // resLevel);
378 // }
379 
381  const ossimIrect& tileRect,
382  ossim_uint32 resLevel)
383 {
385  if ( theCurrentIndex >= size)
386  {
387  return 0;
388  }
389 
391  {
393  }
394 
395  ossimImageSource* temp = 0;
396  ossimRefPtr<ossimImageData> result = 0;
398 
399  double scale = 1.0/std::pow(2.0, (double)resLevel);
400  ossimDpt scalar(scale, scale);
401 
402  while( (theCurrentIndex<size) && !result)
403  {
405  if(!rect.hasNans())
406  {
407  rect = rect * scalar;
408  temp = PTR_CAST(ossimImageSource,
410 
411  if(rect.intersects(tileRect)&&temp)
412  {
413  result = temp->getTile(tileRect, resLevel);
414  status = (result.valid() ?
415  result->getDataObjectStatus():OSSIM_NULL);
416  if((status == OSSIM_NULL)||
417  (status == OSSIM_EMPTY))
418  {
419  result = 0;
420  }
421  }
422  else
423  {
424  status = OSSIM_NULL;
425  result = 0;
426  }
427  }
428  else
429  {
430  status = OSSIM_NULL;
431  result = NULL;
432  }
433 
434  // Go to next source.
435  ++theCurrentIndex;
436  }
437  returnedIdx = theCurrentIndex;
438  if(result.valid())
439  {
440  --returnedIdx;
441  }
442 
443  return result;
444 }
445 
446 
448  const ossim_uint32 startIdx,
449  ossimImageData* tile,
450  ossim_uint32 resLevel)
451 {
452  if (!tile)
453  return false;
454 
456  theCurrentIndex = startIdx;
457 
460 
461  ossimImageSource* temp = 0;
463 
464  double scale = 1.0/std::pow(2.0, (double)resLevel);
465  ossimDpt scalar(scale, scale);
466 
467  while( (theCurrentIndex<size))
468  {
470  if(!rect.hasNans())
471  {
472  rect = rect * scalar;
473  temp = PTR_CAST(ossimImageSource,
475 
476  if(rect.intersects(tile->getImageRectangle()) && temp)
477  {
478  temp->getTile(tile, resLevel);
479  status = tile->getDataObjectStatus();
480  if((status != OSSIM_NULL) && (status != OSSIM_EMPTY))
481  {
482  break;
483  }
484  }
485  }
486 
487  // Go to next source.
488  ++theCurrentIndex;
489  }
490 
491  returnedIdx = theCurrentIndex;
492  if((status == OSSIM_NULL) || (status == OSSIM_EMPTY))
493  {
494  --returnedIdx;
495  return false;
496  }
497 
498  return true;
499 }
500 
501 
502 // ossimRefPtr<ossimImageData> ossimImageCombiner::getNextNormTile(ossim_uint32& returnedIdx,
503 // ossim_uint32 index,
504 // const ossimIpt& origin,
505 // ossim_uint32 resLevel)
506 // {
507 // theCurrentIndex = index;
508 // return getNextNormTile(returnedIdx, origin, resLevel);
509 // }
510 
512  const ossim_uint32 startIdx,
513  const ossimIrect& tileRect,
514  ossim_uint32 resLevel)
515 {
516  theCurrentIndex = startIdx;
517  return getNextNormTile(returnedIdx, tileRect, resLevel);
518 }
519 
520 // ossimRefPtr<ossimImageData> ossimImageCombiner::getNextNormTile(ossim_uint32& returnedIdx,
521 // const ossimIpt& origin,
522 // ossim_uint32 resLevel)
523 // {
524 // ossim_int32 w = getTileWidth();
525 // ossim_int32 h = getTileHeight();
526 
527 // return getNextNormTile(returnedIdx,
528 // ossimIrect(origin.x,
529 // origin.y,
530 // origin.x + w-1,
531 // origin.y + h-1),
532 // resLevel);
533 // }
534 
535 
537  const ossimIrect& tileRect,
538  ossim_uint32 resLevel)
539 {
541 
542  if(theCurrentIndex >= size)
543  {
544  return 0;
545  }
546 
547  if(!theNormTile)
548  {
549  theNormTile = new ossimImageData(this,
552  }
553 
554  ossimRefPtr<ossimImageData> result = getNextTile(returnedIdx, tileRect, resLevel);
555 
556  if(result.valid())
557  {
559  result->getNumberOfBands());
560  result->copyTileToNormalizedBuffer((float*)theNormTile->getBuf());
561 
563  result = theNormTile;
564  }
565 
566  return result;
567 }
568 
570  ossim_uint32 resLevel)const
571 {
573  {
575  }
576  double scale = 1.0/std::pow(2.0, (double)resLevel);
577  ossimDpt scalar(scale, scale);
578  ossim_uint32 result = 0;
579  ossim_uint32 maxIndex = getNumberOfInputs();
580  for(ossim_uint32 inputIndex = 0; inputIndex < maxIndex; ++inputIndex)
581  {
582  if(!theFullResBounds[inputIndex].hasNans())
583  {
584  ossimIrect boundingRect = theFullResBounds[inputIndex] * scalar;
585  if(rect.intersects(boundingRect))
586  {
587  ++result;
588  }
589  }
590  }
591 
592  return result;
593 }
594 
595 void ossimImageCombiner::getOverlappingImages(std::vector<ossim_uint32>& result,
596  const ossimIrect& rect,
597  ossim_uint32 resLevel)const
598 {
600  {
602  }
603  double scale = 1.0/std::pow(2.0, (double)resLevel);
604  ossimDpt scalar(scale, scale);
605 
606  ossim_uint32 inputIndex;
607  ossimIrect boundingRect;
608  for(inputIndex = 0; inputIndex < getNumberOfInputs(); ++inputIndex)
609  {
610  if(!theFullResBounds[inputIndex].hasNans())
611  {
612  boundingRect = theFullResBounds[inputIndex]*scalar;
613  if(rect.intersects(boundingRect))
614  {
615  result.push_back(inputIndex);
616  }
617  }
618  }
619 }
620 
622 {
623  initialize();
624 }
625 
627 {
628  initialize();
629 }
630 
632 {
633  initialize();
634 }
635 
637 {
638  initialize();
639 }
640 
642 {
643  return theHasDifferentInputs;
644 }
645 
647  const char* prefix) const
648 {
649  return ossimImageSource::saveState(kwl, prefix);
650 }
651 
653  const ossimConnectableObject* object)const
654 {
655  return (object&& PTR_CAST(ossimImageSource, object));
656 }
657 
659 {
660 
661  ossim_uint32 inputSize = getNumberOfInputs();
662 
663  if(inputSize)
664  {
665  ossimImageSource* tempInterface=0;
666  if(theFullResBounds.size() != inputSize)
667  {
668  theFullResBounds.resize(inputSize);
669  }
670  for(ossim_uint32 inputIndex = 0; inputIndex < inputSize; ++inputIndex)
671  {
672  tempInterface = PTR_CAST(ossimImageSource, getInput(inputIndex));
673  if(tempInterface)
674  {
675  theFullResBounds[inputIndex] = tempInterface->getBoundingRect();
676  }
677  else
678  {
679  theFullResBounds[inputIndex].makeNan();
680  }
681  }
683  }
684  else
685  {
686  theFullResBounds.clear();
687  }
688 }
virtual void propertyEvent(ossimPropertyEvent &event)
virtual void connectInputEvent(ossimConnectionEvent &event)
virtual bool addListener(ossimListener *listener)
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
This will return the bounding rect of the source.
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
This will return the bounding rect of the source.
ossim_uint32 theInputToPassThrough
virtual ossim_uint32 getNumberOfBands() const
#define CLOG
Definition: ossimTrace.h:23
virtual bool canConnectMyInputTo(ossim_int32 inputIndex, const ossimConnectableObject *object) const
required to be overriden by derived classes
virtual ossim_uint32 getNumberOfInputBands() const
Returns the number of bands available from the input.
This will be a base for all combiners.
Represents serializable keyword/value map.
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
bool valid() const
Definition: ossimRefPtr.h:75
virtual double getMinPixelValue(ossim_uint32 band=0) const
Returns the min pixel of the band.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
virtual void disconnectInputEvent(ossimConnectionEvent &event)
virtual ossimRefPtr< ossimImageData > getNextNormTile(ossim_uint32 &returnedIdx, const ossim_uint32 index, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
virtual void getOverlappingImages(std::vector< ossim_uint32 > &result, const ossimIrect &rect, ossim_uint32 resLevel=0) const
Used to populate the result with the index of the overlapping images.
virtual ossim_uint32 getTileHeight() const
Returns the default processing tile height.
virtual ossimDataObjectStatus getDataObjectStatus() const
ossim_uint32 theCurrentIndex
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
virtual void initialize()
Initialize the data buffer.
virtual ossim_uint32 getTileWidth() const
Returns the default processing tile width.
ossimConnectableObject * getInput(ossim_uint32 index=0)
returns the object at the specified index.
virtual double getMinPixelValue(ossim_uint32 band=0) const
Returns the min pixel of the band.
virtual ossimRefPtr< ossimImageData > getNextTile(ossim_uint32 &returnedIdx, const ossim_uint32 startIdx, const ossimIrect &tileRect, ossim_uint32 resLevel=0)
#define RTTI_DEF2(cls, name, b1, b2)
Definition: ossimRtti.h:493
std::vector< ossimRefPtr< ossimConnectableObject > > ConnectableObjectList
ossim_uint32 theLargestNumberOfInputBands
yy_size_t size
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
virtual void setImageRectangleAndBands(const ossimIrect &rect, ossim_uint32 numberOfBands)
std::vector< ossimIrect > theFullResBounds
unsigned int ossim_uint32
ossimRefPtr< ossimImageData > theNormTile
32 bit normalized floating point
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
virtual ossimIrect getImageRectangle() const
virtual void copyTileToNormalizedBuffer(ossim_float64 *buf) const
Copies entire tile to buf passed in.
OSSIM_DLL ossim_uint32 scalarSizeInBytes(ossimScalarType scalarType)
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
virtual ossim_int32 connectMyInputTo(ossimConnectableObject *inputObject, bool makeOutputConnection=true, bool createEventFlag=true)
Will try to connect this objects input to the passed in object.
#define DBL_EPSILON
virtual ossim_uint32 getNumberOfOverlappingImages(const ossimIrect &rect, ossim_uint32 resLevel=0) const
Used to retrieve the number of overlapping images withint the given rect.
virtual bool hasDifferentInputs() const
ossimScalarType
return status
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
void makeNan()
Definition: ossimIrect.h:329
virtual const void * getBuf() const
virtual ossim_uint32 getNumberOfInputs() const
Returns the number of input objects.
virtual void refreshEvent(ossimRefreshEvent &event)
virtual void setDataObjectStatus(ossimDataObjectStatus status) const
Full list found in ossimConstants.h.
bool hasNans() const
Definition: ossimIrect.h:337
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
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 ossim_uint32 getTileHeight() const
Returns the default processing tile height.
ossimIrect combine(const ossimIrect &rect) const
Definition: ossimIrect.cpp:543
virtual void updateRects()
This will go through and precompute the bounding rects of each input image.
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
virtual ossim_uint32 getTileWidth() const
Returns the default processing tile width.
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
virtual bool removeListener(ossimListener *listener)