OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimImageHandlerMtAdaptor.cpp
Go to the documentation of this file.
1 //**************************************************************************************************
2 // OSSIM -- Open Source Software Image Map
3 //
4 // LICENSE: See top level LICENSE.txt file.
5 //
6 // AUTHOR: Oscar Kramer
7 //
10 //
11 //**************************************************************************************************
12 // $Id$
15  // #include <ossim/parallel/ossimMtDebug.h>
16 #include <ossim/base/ossimCommon.h>
17 #include <ossim/base/ossimTimer.h>
18 #include <ossim/base/ossimTrace.h>
19 #include <cstdio>
20 #include <ctime>
21 // #include <sys/time.h>
22 
23 RTTI_DEF1(ossimImageHandlerMtAdaptor, "ossimImageHandlerMtAdaptor", ossimImageHandler);
24 
25 const char* ossimImageHandlerMtAdaptor::ADAPTEE_ID_KW = "adaptee_id";
26 static ossimTrace traceDebug = ossimTrace("ossimImageHandlerMtAdaptor:debug");
27 
28 //**************************************************************************************************
29 // Constructor
30 //**************************************************************************************************
32  : d_getTileT (0),
33  d_cacheTileSize(1024),
34  m_adaptedHandler (0),
35  m_cache (0),
36  d_useCache (false),
37  d_useFauxTile (false)
38 {
39  //###### DEBUG ############
40  // ossimMtDebug* mt_debug = ossimMtDebug::instance();
41  //d_useCache = mt_debug->handlerCacheEnabled;
42  //d_useFauxTile = mt_debug->handlerUseFauxTile;
43  //###### END DEBUG ############
44 
45  setUseCache(use_cache);
46  setCacheTileSize(cache_tile_size);
47  setAdaptee(adaptee);
48 }
49 
50 //**************************************************************************************************
51 // Destructor
52 //**************************************************************************************************
54 {
55  m_adaptedHandler = 0;
56  m_cache = 0;
57  d_fauxTile = 0;
58 }
59 
60 //**************************************************************************************************
62 //**************************************************************************************************
64 {
65  m_adaptedHandler = handler;
66  if (handler == NULL)
67  return;
68 
69  // Fetch the adaptee's output list and make it our own:
70  ConnectableObjectList output_list = handler->getOutputList();
71 
72  if (d_useCache)
73  {
74  // Create the cache and connect this adaptor as its output:
77  m_cache->connectMyOutputTo(this, true, false);
78  m_cache->changeOwner(this);
79  //m_cache->connectMyOutputTo(this, true, false);
80  handler->disconnectMyOutputs(output_list, true, false);
81  handler->connectMyOutputTo(m_cache.get(), true, true);
82  }
83  else
84  {
85  handler->disconnectMyOutputs(output_list, true, false);
86  handler->connectMyOutputTo(this, true, false);
87  }
88 
89  // Finally connect the adaptee's outputs to this and fire connection events:
90  connectMyOutputTo(output_list, true, true);
91  handler->changeOwner(this);
92 
93  if (d_useFauxTile)
94  {
95  d_fauxTile = (ossimImageData*) handler->getTile(ossimIpt(0,0), 0)->dup();
96  //d_fauxTile = new ossimImageData(this,
97  // handler->getOutputScalarType(),
98  // handler->getNumberOfOutputBands(),
99  // handler->getTileWidth(),
100  // handler->getTileHeight());
101  //d_fauxTile->fill(128.0);
102  }
103 }
104 
105 //**************************************************************************************************
107 //**************************************************************************************************
109  const ossimConnectableObject* obj) const
110 {
111  const ossimImageHandler* h = dynamic_cast<const ossimImageHandler*>(obj);
112  if ((inputIndex == 0) && (h != NULL))
113  return true;
114  return false;
115 }
116 
117 
118 //**************************************************************************************************
121 //**************************************************************************************************
124 {
125  if (!m_adaptedHandler.valid())
126  return NULL;
127 
128  // Establish tile rect to call overloaded getTile(tile_rect):
131  ossimIpt lr (origin.x + w - 1, origin.y + h - 1);
132  ossimIrect tile_rect (origin, lr);
133 
134  // Need to unlock to prevent freezing in the called getTile():
135  return getTile(tile_rect, rLevel);
136 }
137 
138 //**************************************************************************************************
141 //**************************************************************************************************
144 {
145  if (traceDebug())
146  {
147  std::cout << "TILE: " << tile_rect << std::endl;
148  }
149 
150  if (d_useFauxTile)
151  {
153  ftile->setOrigin(tile_rect.ul());
154  return ftile;
155  }
156 
157  if (!m_adaptedHandler.valid())
158  return NULL;
159 
160  // The sole purpose of the adapter is this mutex lock around the actual handler getTile:
161  //std::lock_guard<std::mutex> lock(m_mutex);
162 
164  ossimRefPtr<ossimImageData> temp_tile = 0;
165  double dt = ossimTimer::instance()->time_s();
166 
167  //writeTime();
168  if (traceDebug())
169  {
170  std::cout << "WAIT LOCK: " << tile_rect << std::endl;
171  }
172  std::lock_guard<std::mutex> lock(m_mutex);
173 
174  if (traceDebug())
175  {
176  std::cout << "START LOCK: " << tile_rect << std::endl;
177  }
178 
179  if (d_useCache)
180  temp_tile = m_cache->getTile(tile_rect, rLevel);
181  else
182  temp_tile = m_adaptedHandler->getTile(tile_rect, rLevel);
184 
185  // We make our own instance of a tile and copy the adaptee's returned tile to it. This avoids
186  // the product tile from changing while being processed up the chain. The adaptee's tile can
187  // change as soon as the mutex lock is released:
188 
189  if (temp_tile.valid())
190  *tile = *(temp_tile.get());
191  else
192  tile = NULL;
193 
194  //writeTime();
195  if (traceDebug())
196  {
197  std::cout << "END LOCK: " << tile_rect << std::endl;
198  }
199  if (traceDebug())
200  {
201  std::cout << "END TILE: " << tile_rect << std::endl;
202  }
203 
204  return tile;
205 }
206 
207 //**************************************************************************************************
210 //**************************************************************************************************
212 {
213  if ((!m_adaptedHandler.valid()) || (tile == NULL))
214  return false;
215 
216  // The sole purpose of the adapter is this mutex lock around the actual handler getTile:
217  std::lock_guard<std::mutex> lock(m_mutex);
218 
219  // This is effectively a copy of ossimImageSource::getTile(ossimImageData*). It is reimplemented
220  // here to save two additional function calls:
221  tile->ref();
222  bool status = true;
223  ossimIrect tile_rect = tile->getImageRectangle();
224 
225  ossimRefPtr<ossimImageData> temp_tile = 0;
226  if (d_useCache)
227  temp_tile = m_cache->getTile(tile_rect, rLevel);
228  else
229  temp_tile = m_adaptedHandler->getTile(tile_rect, rLevel);
230 
231  if (temp_tile.valid())
232  *tile = *(temp_tile.get());
233  else
234  status = false;
235  tile->unref();
236 
237  return status;
238 }
239 
240 //**************************************************************************************************
243 //**************************************************************************************************
244 bool ossimImageHandlerMtAdaptor::saveState(ossimKeywordlist& kwl, const char* prefix)const
245 {
246  if (!m_adaptedHandler.valid())
247  return false;
248 
249  // Skip the ossimImageHandler::saveState() since it is not necessary here:
250  ossimImageSource::saveState(kwl, prefix);
251 
252  kwl.add(prefix, ADAPTEE_ID_KW, m_adaptedHandler->getId().getId());
253 
254  return true;
255 }
256 
257 //**************************************************************************************************
260 //**************************************************************************************************
261 bool ossimImageHandlerMtAdaptor::loadState(const ossimKeywordlist& kwl, const char* prefix)
262 {
263  m_adaptedHandler = 0;
264 
265  // Skip the ossimImageHandler::loadState() since it is not necessary here:
266  if (!ossimImageSource::loadState(kwl, prefix))
267  return false;
268 
269  // The adaptee's ID at least will be in the KWL:
270  ossimString value = kwl.find(prefix, ADAPTEE_ID_KW);
271  if (value.empty())
272  return false;
273 
274  return true;
275 }
276 
277 //**************************************************************************************************
278 // The following are virtuals in the base class. Implemented here as pass-through to adaptee
279 //**************************************************************************************************
281 {
282  if (m_adaptedHandler.valid())
284  return 0;
285 }
286 
288 {
289  if (m_adaptedHandler.valid())
290  return m_adaptedHandler->isOpen();
291  return false;
292 }
293 
295 {
296  if (m_adaptedHandler.valid())
297  return m_adaptedHandler->open();
298  return false;
299 }
300 
302 {
303  if (m_adaptedHandler.valid())
304  return m_adaptedHandler->getNumberOfLines(resLevel);
305  return 0;
306 }
307 
309 {
310  if (m_adaptedHandler.valid())
311  return m_adaptedHandler->getNumberOfSamples(resLevel);
312  return 0;
313 }
314 
316 {
317  if (m_adaptedHandler.valid())
319  return 0;
320 }
321 
323 {
324  if (m_adaptedHandler.valid())
326  return 0;
327 }
328 
330 {
331  if (m_adaptedHandler.valid())
332  return m_adaptedHandler->getLongName();
333  return ossimString();
334 }
335 
337 {
338  if (m_adaptedHandler.valid())
339  return m_adaptedHandler->getShortName();
340  return ossimString();
341 }
342 
344 {
346  this->disconnectAllOutputs();
347  m_cache = 0;
348  if (m_adaptedHandler.valid())
349  {
352  }
353  d_fauxTile = 0;
354 }
355 
357 {
358  if (m_adaptedHandler.valid())
360  return 0;
361 }
362 
364 {
365  d_useCache = use_cache;
366 }
367 
369 {
370  d_cacheTileSize = cache_tile_size;
371 }
372 
374 {
375  if (m_adaptedHandler.valid())
377  return 0;
378 }
379 
381 {
382 #if 0 /* not portable (drb) */
383  struct timeval tv;
384  struct timezone tz;
385  struct tm *tm;
386  gettimeofday(&tv, &tz);
387  tm=localtime(&tv.tv_sec);
388  printf("%d:%02d:%02d.%ld ", tm->tm_hour, tm->tm_min,tm->tm_sec,tv.tv_usec);
389 #endif
390  // Sorry no usecs...
391  time_t rawTime = (time_t)ossim::getTime();
392  char buf[9];
393  strftime(buf, 9, "%H:%M:%S", gmtime(&rawTime));
394  cerr << buf << std::endl;
395 }
396 
398 {
399  if (m_adaptedHandler.valid())
401  return OSSIM_SCALAR_UNKNOWN;
402 }
403 
405 {
406  if (m_adaptedHandler.valid())
407  return m_adaptedHandler->getTileWidth();
408  return 0;
409 }
410 
412 {
413  if (m_adaptedHandler.valid())
415  return 0;
416 }
417 
419 {
420  if (m_adaptedHandler.valid())
421  return m_adaptedHandler->getMinPixelValue(band);
422  return 0.0;
423 }
424 
426 {
427  if (m_adaptedHandler.valid())
428  return m_adaptedHandler->getMaxPixelValue(band);
429  return 0.0;
430 }
431 
433 {
434  if (m_adaptedHandler.valid())
435  return m_adaptedHandler->getNullPixelValue(band);
436  return 0.0;
437 }
438 
virtual bool open()=0
Pure virtual open.
virtual ossim_uint32 getImageTileWidth() const
Returns the tile width of the image or 0 if the image is not tiled.
ossimRefPtr< ossimImageHandler > m_adaptedHandler
OSSIM_DLL ossim_int64 getTime()
Gets the current time.
virtual void disconnectAllOutputs()
Will disconnect all of the output objects.
virtual bool isOpen() const
Derived classes must implement this method to be concrete.
Intended mainly to provide a mechanism for mutex-locking access to a shared resource during a getTile...
virtual ossim_uint32 getImageTileHeight() const
Returns the tile width of the image or 0 if the image is not tiled.
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 bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
virtual ossim_uint32 getTileHeight() const
Returns the default processing tile height.
const char * find(const char *key) const
virtual ossim_uint32 getTileWidth() const
Returns the default processing tile width.
virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
virtual ossim_uint32 getTileHeight() const
Returns the default processing tile height.
virtual ~ossimImageHandlerMtAdaptor()
Protected destructor forces using reference pointer for instantiation.
virtual ossim_float64 getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
virtual ossimString getLongName() const
const ossimIpt & ul() const
Definition: ossimIrect.h:274
void setAdaptee(ossimImageHandler *handler)
Sets the handler being adapted.
virtual void closeOverview()
If theOverview is initialized it will be deleted and set to NULL.
virtual ossim_float64 getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
virtual bool canConnectMyInputTo(ossim_int32 i, const ossimConnectableObject *obj) const
Only an ossimImageHandler is allowed as input here.
virtual bool open()
Pure virtual open.
ossim_int64 getId() const
Definition: ossimId.h:29
virtual ossimString getShortName() const
Definition: ossimObject.cpp:48
ossimImageHandlerMtAdaptor(ossimImageHandler *adaptee=0, bool use_cache=false, ossim_uint32 cache_tile_size=64)
void ref() const
increment the reference count by one, indicating that this object has another pointer which is refere...
virtual ossim_uint32 getTileWidth() const
Returns the default processing tile width.
virtual ossimObject * dup() const
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
virtual ossim_uint32 getNumberOfDecimationLevels() const
This returns the total number of decimation levels.
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
virtual bool isOpen() const =0
Derived classes must implement this method to be concrete.
virtual double getMinPixelValue(ossim_uint32 band=0) const
Retuns the min pixel value.
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
std::vector< ossimRefPtr< ossimConnectableObject > > ConnectableObjectList
virtual void changeOwner(ossimObject *owner)
Permits changing the object&#39;s owner.
virtual ossim_float64 getMinPixelValue(ossim_uint32 band=0) const
Retuns the min pixel value.
const ossimId & getId() const
Will allow us to get this object&#39;s id.
static ossimTimer * instance()
Definition: ossimTimer.cpp:19
virtual ossim_uint32 getImageTileHeight() const =0
Returns the tile width of the image or 0 if the image is not tiled.
double time_s() const
Get elapsed time in seconds.
Definition: ossimTimer.h:33
unsigned int ossim_uint32
virtual ossim_uint32 getNumberOfDecimationLevels() const
This returns the total number of decimation levels.
Cache Tile Source.
void setTileSize(const ossimIpt &size)
Set the tile size.
virtual ossimIrect getImageRectangle() const
virtual ossimString getLongName() const
Definition: ossimObject.cpp:53
virtual void close()
Deletes the overview and clears the valid image vertices.
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const
Pure virtual, derived classes must implement.
virtual ossimString getShortName() const
ossimScalarType
void unref() const
decrement the reference count by one, indicating that a pointer to this object is referencing it...
virtual void setOrigin(const ossimIpt &origin)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
return status
const ConnectableObjectList & getOutputList() const
virtual ossim_uint32 getImageTileWidth() const =0
Returns the tile width of the image or 0 if the image is not tiled.
virtual ossim_int32 connectMyOutputTo(ossimConnectableObject *outputObject, bool makeInputConnection=true, bool createEventFlag=true)
Will try to connect this objects output to the passed in object.
ossimRefPtr< ossimCacheTileSource > m_cache
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
virtual void close()
Deletes the overview and clears the valid image vertices.
This class defines an abstract Handler which all image handlers(loaders) should derive from...
ossim_int32 y
Definition: ossimIpt.h:142
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
virtual ossim_uint32 getNumberOfInputBands() const
bool empty() const
Definition: ossimString.h:411
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
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 ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const
Pure virtual, derived classes must implement.
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
ossim_int32 x
Definition: ossimIpt.h:141
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
virtual ossim_uint32 getNumberOfInputBands() const =0
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
Intercepts the getTile call intended for the adaptee and sets a mutex lock around the adaptee&#39;s getTi...
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
ossimRefPtr< ossimImageData > d_fauxTile
RTTI_DEF1(ossimImageHandlerMtAdaptor, "ossimImageHandlerMtAdaptor", ossimImageHandler)
Intended mainly to provide a mechanism for mutex-locking access to a shared resource during a getTile...
int ossim_int32
virtual void disconnectMyOutputs(ConnectableObjectList &outputList, bool disconnectOutputFlag=true, bool createEventFlag=true)
void setCacheTileSize(ossim_uint32 cache_tile_size)
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
virtual bool removeListener(ossimListener *listener)