1 //*******************************************************************
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: David Burken
8 //
9 // Description:
10 //
11 // This class defines an abstract image handler which all loaders should
12 // derive from.
13 //
14 //*******************************************************************
15 // $Id: ossimImageHandler.cpp 23013 2014-12-02 19:21:56Z okramer $
16
17 #include <ossim/imaging/ossimImageHandler.h>
18 #include <ossim/base/ossimBooleanProperty.h>
19 #include <ossim/base/ossimCommon.h>
20 #include <ossim/base/ossimException.h>
21 #include <ossim/base/ossimContainerEvent.h>
22 #include <ossim/base/ossimEventIds.h>
23 #include <ossim/base/ossimFilenameProperty.h>
24 #include <ossim/base/ossimNumericProperty.h>
25 #include <ossim/base/ossimStringProperty.h>
26 #include <ossim/base/ossimKeywordlist.h>
27 #include <ossim/base/ossimKeywordNames.h>
28 #include <ossim/base/ossimNotify.h>
29 #include <ossim/base/ossimPolygon.h>
30 #include <ossim/base/ossimPreferences.h>
31 #include <ossim/base/ossimStdOutProgress.h>
32 #include <ossim/base/ossimTrace.h>
33 #include <ossim/base/ossimScalarTypeLut.h>
34 #include <ossim/imaging/ossimHistogramWriter.h>
35 #include <ossim/imaging/ossimImageGeometryRegistry.h>
36 #include <ossim/imaging/ossimImageHandlerRegistry.h>
37 #include <ossim/imaging/ossimImageHistogramSource.h>
38 #include <ossim/imaging/ossimTiffTileSource.h>
39 #include <ossim/imaging/ossimTiffOverviewBuilder.h>
40 #include <ossim/projection/ossimProjection.h>
41 #include <ossim/projection/ossimProjectionFactoryRegistry.h>
42 #include <algorithm>
43
44 using namespace std;
45
46 RTTI_DEF1(ossimImageHandler, "ossimImageHandler", ossimImageSource)
47
48 // Static trace for debugging
49 static ossimTrace traceDebug("ossimImageHandler:debug");
50
51 // Property keywords.
52 static const char HAS_LUT_KW[] = "has_lut";
53 static const char OPEN_OVERVIEW_FLAG_KW[] = "open_overview_flag";
54 static const char START_RES_LEVEL_KW[] = "start_res_level";
55 static const char SUPPLEMENTARY_DIRECTORY_KW[] = "supplementary_directory";
56 static const char VALID_VERTICES_FILE_KW[] = "valid_vertices_file";
57
58 #ifdef OSSIM_ID_ENABLED
59 static const char OSSIM_ID[] = "$Id: ossimImageHandler.cpp 23013 2014-12-02 19:21:56Z okramer $";
60 #endif
61
62 // GARRETT! All of the decimation factors are scattered throughout. We want to fold that into
63 // the image geometry object. The code is ready in ossimImageGeometry for this (more or less), but
64 // the ossimImageGeometry::m_decimationFactors is not being set nor referenced. Can you do this?
65 // I'm a little foggy on how we want to incorporate R-level scaling into the geometry object.
66
ossimImageHandler()67 ossimImageHandler::ossimImageHandler()
68 :
69 ossimImageSource(0, 0, 0, true, false /* output list is not fixed */ ),
70 theImageFile(ossimFilename::NIL),
71 theOverviewFile(ossimFilename::NIL),
72 theSupplementaryDirectory(ossimFilename::NIL),
73 theOverview(0),
74 theValidImageVertices(0),
75 theMetaData(),
76 theGeometry(),
77 theLut(0),
78 theDecimationFactors(0),
79 theImageID(""),
80 theStartingResLevel(0),
81 theOpenOverviewFlag(true),
82 thePixelType(OSSIM_PIXEL_IS_POINT)
83 {
84 if (traceDebug())
85 {
86 ossimNotify(ossimNotifyLevel_DEBUG)
87 << "ossimImageHandler::ossimImageHandler() DEBUG:" << std::endl;
88 #ifdef OSSIM_ID_ENABLED
89 ossimNotify(ossimNotifyLevel_DEBUG)
90 << "OSSIM_ID: "
91 << OSSIM_ID
92 << std::endl;
93 #endif
94 }
95
96 // Check for global preference supplementary dir.
97 theSupplementaryDirectory.string() = ossimPreferences::instance()->
98 preferencesKWL().findKey( std::string("ossim_supplementary_directory") );
99 }
100
~ossimImageHandler()101 ossimImageHandler::~ossimImageHandler()
102 {
103 theOverview = 0;
104 }
105
initialize()106 void ossimImageHandler::initialize()
107 {
108 }
109
110 //*******************************************************************
111 // Public method:
112 //*******************************************************************
saveState(ossimKeywordlist & kwl,const char * prefix) const113 bool ossimImageHandler::saveState(ossimKeywordlist& kwl,
114 const char* prefix) const
115 {
116 static const char MODULE[] = "ossimImageHandler::saveState";
117
118 ossimImageSource::saveState(kwl, prefix);
119 if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
120 {
121 ossimNotify(ossimNotifyLevel_WARN)
122 << MODULE
123 << " ERROR detected in keyword list! State not saved."
124 << std::endl;
125 return false;
126 }
127
128 kwl.add(prefix, ossimKeywordNames::FILENAME_KW, theImageFile.c_str(), true);
129 kwl.add(prefix, HAS_LUT_KW, (theLut.valid()?"true":"false"), true);
130 kwl.add(prefix, ossimKeywordNames::IMAGE_ID_KW, theImageID, true);
131 kwl.add(prefix, ossimKeywordNames::OVERVIEW_FILE_KW, theOverviewFile.c_str(), true);
132 kwl.add(prefix, SUPPLEMENTARY_DIRECTORY_KW, theSupplementaryDirectory.c_str(), true);
133 kwl.add(prefix, START_RES_LEVEL_KW, theStartingResLevel, true);
134 kwl.add(prefix, OPEN_OVERVIEW_FLAG_KW, (theOpenOverviewFlag?"1":"0"), true);
135 kwl.add(prefix, ossimKeywordNames::PIXEL_TYPE_KW, (ossim_uint16) thePixelType, true);
136
137 return true;
138 }
139
140 //*******************************************************************
141 // Public method:
142 //*******************************************************************
loadState(const ossimKeywordlist & kwl,const char * prefix)143 bool ossimImageHandler::loadState(const ossimKeywordlist& kwl,
144 const char* prefix)
145 {
146 static const char MODULE[] = "ossimImageHandler::loadState(kwl, prefix)";
147 theDecimationFactors.clear();
148 if(traceDebug())
149 {
150 ossimNotify(ossimNotifyLevel_DEBUG)
151 << MODULE << " DEBUG: entered ..."
152 << std::endl;
153 }
154
155 ossimImageSource::loadState(kwl, prefix);
156
157 if (kwl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR)
158 {
159 ossimNotify(ossimNotifyLevel_WARN)
160 << MODULE
161 << "WARNING: error detected in keyword list! State not load."
162 << std::endl;
163
164 if(traceDebug())
165 {
166 ossimNotify(ossimNotifyLevel_DEBUG)
167 << MODULE << " DEBUG: "
168 << "leaving with error in kwl ..." << std::endl;
169 }
170 return false;
171 }
172
173 const char* lookup = kwl.find(prefix, ossimKeywordNames::FILENAME_KW);
174 if (!lookup)
175 {
176 // Deprecated...
177 lookup = kwl.find(prefix, ossimKeywordNames::IMAGE_FILE_KW);
178 }
179
180 if (lookup)
181 {
182 theImageFile = lookup;
183 }
184
185 lookup = kwl.find(prefix, ossimKeywordNames::OVERVIEW_FILE_KW);
186 if(lookup)
187 {
188 theOverviewFile = ossimFilename(lookup);
189 }
190 if(traceDebug())
191 {
192 ossimNotify(ossimNotifyLevel_DEBUG)
193 << MODULE << " DEBUG:\n"
194 << "filename = " << theImageFile << std::endl;
195 }
196
197 // Check for an external geometry file to initialize our image geometry object:
198 lookup = kwl.find(prefix, ossimKeywordNames::GEOM_FILE_KW);
199 if (lookup)
200 {
201 ossimKeywordlist geomKwl;
202 if (geomKwl.addFile(lookup) == true)
203 {
204 theGeometry = new ossimImageGeometry;
205 theGeometry->loadState(geomKwl);
206 if(traceDebug())
207 {
208 ossimNotify(ossimNotifyLevel_DEBUG)
209 << MODULE << " DEBUG:"
210 << "Loaded external geometry file: "
211 << lookup
212 << "\n" << geomKwl << std::endl;
213 }
214 }
215 }
216
217 // Check for an valid image vetices file.
218 lookup = kwl.find(prefix, VALID_VERTICES_FILE_KW);
219 if (lookup)
220 {
221 initVertices(lookup);
222 }
223
224 // Starting resolution level.
225 lookup = kwl.find(prefix, START_RES_LEVEL_KW);
226 if (lookup)
227 {
228 theStartingResLevel = ossimString(lookup).toUInt32();
229 }
230
231 // Open overview flag.
232 lookup = kwl.find(prefix, OPEN_OVERVIEW_FLAG_KW);
233 if (lookup)
234 {
235 setOpenOverviewFlag( ossimString(lookup).toBool() );
236 }
237
238 // The supplementary directory for finding the overview
239 lookup = kwl.find(prefix, SUPPLEMENTARY_DIRECTORY_KW);
240 if (lookup)
241 {
242 theSupplementaryDirectory = ossimFilename(lookup);
243 }
244
245 if(getNumberOfInputs())
246 {
247 theInputObjectList.clear();
248 }
249 theInputListIsFixedFlag = true;
250
251 // Read image id if present:
252 theImageID = kwl.find(prefix, ossimKeywordNames::IMAGE_ID_KW);
253
254 lookup = kwl.find(prefix, ossimKeywordNames::PIXEL_TYPE_KW);
255 if (lookup)
256 {
257 thePixelType = (ossimPixelType) atoi(lookup);
258 }
259
260 if(traceDebug())
261 {
262 ossimNotify(ossimNotifyLevel_DEBUG)
263 << MODULE << " DEBUG: Leaving Ok ..."
264 << std::endl;
265 }
266 return true;
267 }
268
initVertices(const char * file)269 bool ossimImageHandler::initVertices(const char* file)
270 {
271 static const char MODULE[] = "ossimImageHandler::initVertices";
272 bool loadFromFileFlag = true;
273 std::shared_ptr<ossimKeywordlist> kwl;
274 if(m_state)
275 {
276 bool validVerticesFlag = false;
277 if(m_state->getValidVertices())
278 {
279 loadFromFileFlag = false;
280 kwl = m_state->getValidVertices();
281 if(kwl)
282 {
283 ossimString connectionString = kwl->find("connection_string");
284 if(connectionString != file)
285 {
286 loadFromFileFlag = true;
287 }
288 else if(kwl->getSize()<=0)
289 {
290 return false;
291 }
292 }
293 }
294 else
295 {
296 loadFromFileFlag = true;
297 }
298 }
299 if(!kwl) kwl = std::make_shared<ossimKeywordlist>();
300
301 if(loadFromFileFlag)
302 {
303 kwl = std::make_shared<ossimKeywordlist>();
304 std::shared_ptr<ossim::istream> instream = ossim::StreamFactoryRegistry::instance()->createIstream(file);
305 kwl->add("connection_string", file, true);
306 if (!instream)
307 {
308 //if(m_state)
309 // m_state->setValidVertices(kwl);
310 return false;
311 }
312
313 kwl->parseStream(*instream);
314 if(m_state && kwl->getSize())
315 m_state->setValidVertices(kwl);
316 }
317
318 if (kwl->getErrorStatus() != ossimErrorCodes::OSSIM_OK)
319 {
320 if (traceDebug())
321 {
322 ossimNotify(ossimNotifyLevel_DEBUG)
323 << "ossimImageHandler::initVertices NOTICE:"
324 << "\nError reading valid vertice file: " << file << std::endl;
325 }
326 return false;
327 }
328
329 // Clean out any old vertices...
330 theValidImageVertices.clear();
331 std::vector<ossimString> indexedPrefixes;
332 kwl->getSortedList(indexedPrefixes, "point");
333 ossim_uint32 number_of_points = indexedPrefixes.size();
334 for (ossim_uint32 i=0; i<number_of_points; i++)
335 {
336 ossimIpt pt;
337 const char* lookup;
338 lookup = kwl->find(indexedPrefixes[i], ".x");
339 if (lookup)
340 {
341 pt.x = atoi(lookup);
342 lookup = kwl->find(indexedPrefixes[i], ".y");
343 if (lookup)
344 pt.y = atoi(lookup);
345 }
346
347 if (!lookup)
348 {
349 if (traceDebug())
350 CLOG << " ERROR: lookup failed for: " << indexedPrefixes[i] << std::endl;
351 return false;
352 }
353
354 theValidImageVertices.push_back(pt);
355 }
356
357
358 if (traceDebug())
359 {
360 CLOG << " DEBUG:"
361 << "\nVertices file: " << file
362 << "\nValid image vertices:"
363 << std::endl;
364 for (ossim_uint32 i=0; i<theValidImageVertices.size(); ++i)
365 {
366 ossimNotify(ossimNotifyLevel_DEBUG)
367 << "\npoint[" << i << "]: " << theValidImageVertices[i];
368 }
369 ossimNotify(ossimNotifyLevel_DEBUG) << std::endl;
370 }
371
372 return true;
373 }
374
getNumberOfDecimationLevels() const375 ossim_uint32 ossimImageHandler::getNumberOfDecimationLevels() const
376 {
377 ossim_uint32 result = 1; // Add r0
378 if (theOverview.valid())
379 {
380 result += theOverview->getNumberOfDecimationLevels();
381 }
382 return result;
383 }
384
getNumberOfReducedResSets() const385 ossim_uint32 ossimImageHandler::getNumberOfReducedResSets() const
386 {
387 return getNumberOfDecimationLevels();
388 }
389
getImageRectangle(ossim_uint32 resLevel) const390 ossimIrect ossimImageHandler::getImageRectangle(ossim_uint32 resLevel) const
391 {
392 ossimIrect result;
393
394 if( isOpen() && isValidRLevel(resLevel) )
395 {
396 ossim_int32 lines = getNumberOfLines(resLevel);
397 ossim_int32 samples = getNumberOfSamples(resLevel);
398 if( !lines || !samples )
399 {
400 result.makeNan();
401 }
402 else
403 {
404 result = ossimIrect(0, 0, samples-1, lines-1);
405 }
406 }
407 else
408 {
409 result.makeNan();
410 }
411
412 return result;
413 }
414
getBoundingRect(ossim_uint32 resLevel) const415 ossimIrect ossimImageHandler::getBoundingRect(ossim_uint32 resLevel) const
416 {
417 return getImageRectangle(resLevel);
418 }
419
420
getDecimationFactor(ossim_uint32 resLevel,ossimDpt & result) const421 void ossimImageHandler::getDecimationFactor(ossim_uint32 resLevel, ossimDpt& result) const
422 {
423 if (resLevel < theDecimationFactors.size())
424 result = theDecimationFactors[resLevel];
425 else
426 result.makeNan();
427 }
428
getDecimationFactors(vector<ossimDpt> & decimations) const429 void ossimImageHandler::getDecimationFactors(vector<ossimDpt>& decimations) const
430 {
431 decimations = theDecimationFactors;
432 }
433
434 //*************************************************************************************************
435 // Method determines the decimation factors at each resolution level. This
436 // base class implementation computes the decimation by considering the ratios in image size
437 // between resolution levels, with fuzzy logic for rounding ratios to the nearest power of 2
438 // if possible. Derived classes need to override this method if the decimations are provided
439 // as part of the image metadata. In some cases (cf. ossimNitfTileSource), the derived class can
440 // set the first R-level (R0) decimation in the case that it is not unity, and then invoke this
441 // base class implementation to compute remaining R-levels, respecting the R0 decimation previously
442 // set by derived class.
443 //*************************************************************************************************
establishDecimationFactors()444 void ossimImageHandler::establishDecimationFactors()
445 {
446 double line_decimation, samp_decimation, decimation, ratio;
447 ossim_uint32 num_lines, num_samps;
448
449 // The error margin here is effectively the percent error tolerated between ideal number of
450 // pixels for given power-of-2 decimation, and the actual number of pixels found at this
451 // decimation level. Typically, the last level will have fewer pixels than expected, hence the
452 // need for this logic...
453 static const double ERROR_MARGIN = 1.1; // 10% allowance
454
455 // NOTE -- Until the end of this method, all decimation values are actually inverse quantities,
456 // i.e., a decimation of 0.5 typical for rlevel 1 is represented here as 2. This facilitates the
457 // fuzzy logic for recognizing powers of 2 (as integers)
458
459 // Default implementation assumes R0 is not decimated. Check for R0 defined by derived class
460 // however, in case this is not the case:
461 ossimDpt decimation_r0 (1.0, 1.0);
462 if (theDecimationFactors.size() > 0)
463 {
464 decimation_r0.x = 1.0/theDecimationFactors[0].x; // note use of inverse decimation
465 decimation_r0.y = 1.0/theDecimationFactors[0].y;
466 }
467 else
468 theDecimationFactors.push_back(decimation_r0);
469
470 // Variables used in loop below:
471 ossim_uint32 num_lines_r0 = getNumberOfLines(0);
472 ossim_uint32 num_samps_r0 = getNumberOfSamples(0);
473 ossim_uint32 power_of_2_decimation = (ossim_uint32) decimation_r0.x;
474
475 // Remaining res levels are computed as a ratio of image size at R0 to image size at Rn:
476 ossim_uint32 nRlevels = getNumberOfDecimationLevels();
477 for(ossim_uint32 res_level = 1; res_level < nRlevels; ++res_level)
478 {
479 num_lines = getNumberOfLines(res_level);
480 num_samps = getNumberOfSamples(res_level);
481
482 if ((num_lines < 2) || (num_samps < 2))
483 break;
484
485 line_decimation = decimation_r0.y * num_lines_r0 / (double)num_lines;
486 samp_decimation = decimation_r0.x * num_samps_r0 / (double)num_samps;
487 decimation = line_decimation<samp_decimation ? line_decimation:samp_decimation;
488
489 // Check for possible error due to inexact ratios.
490 // Loop until reasonable effort was made to establish the corresponding power-of-2 decimation.
491 // If close match is found, the exact integer value is assigned:
492 do
493 {
494 power_of_2_decimation *= 2;
495 ratio = (double)power_of_2_decimation / decimation;
496 if (ratio < 1.0)
497 ratio = 1.0/ratio;
498 if (ratio < ERROR_MARGIN)
499 decimation = (double) power_of_2_decimation;
500
501 } while ((double) power_of_2_decimation < decimation);
502
503 // Convert the computed decimation back to fractional form before saving in the factors list:
504 decimation = 1.0/decimation;
505 theDecimationFactors.push_back(ossimDpt(decimation, decimation));
506 }
507 }
508
buildHistogram(int numberOfRLevels,ossimHistogramMode mode)509 bool ossimImageHandler::buildHistogram( int numberOfRLevels,
510 ossimHistogramMode mode )
511 {
512 if(isOpen())
513 {
514 ossimFilename file =
515 getFilenameWithThisExtension(ossimString(".his"));
516
517 ossimRefPtr<ossimImageHistogramSource> histoSource = new ossimImageHistogramSource;
518 ossimRefPtr<ossimHistogramWriter> writer = new ossimHistogramWriter;
519
520 if(numberOfRLevels)
521 {
522 histoSource->setMaxNumberOfRLevels(numberOfRLevels);
523 }
524 else
525 {
526 histoSource->setMaxNumberOfRLevels(getNumberOfDecimationLevels());
527 }
528
529 //---
530 // Note if mode==OSSIM_HISTO_MODE_UNKNOWN the histoSource defaults to
531 // normal mode.
532 //---
533 histoSource->setComputationMode( mode );
534
535 histoSource->connectMyInputTo(0, this);
536 histoSource->enableSource();
537 writer->connectMyInputTo(0, histoSource.get());
538 writer->setFilename(file);
539 writer->addListener(&theStdOutProgress);
540 writer->execute();
541 histoSource->disconnect();
542 writer->disconnect();
543 histoSource = 0;
544 writer = 0;
545 }
546 else
547 {
548 return false;
549 }
550
551 return true;
552 }
553
buildAllHistograms(int numberOfRLevels,ossimHistogramMode mode)554 bool ossimImageHandler::buildAllHistograms( int numberOfRLevels,
555 ossimHistogramMode mode )
556 {
557 ossim_uint32 currentEntry = getCurrentEntry();
558 std::vector<ossim_uint32> entryList;
559 getEntryList(entryList);
560 ossim_uint32 idx = 0;
561 for(idx = 0; idx < entryList.size(); ++idx)
562 {
563 setCurrentEntry(entryList[idx]);
564 if(!buildHistogram( numberOfRLevels, mode ))
565 {
566 setCurrentEntry(currentEntry);
567 return false;
568 }
569 }
570
571 setCurrentEntry(currentEntry);
572 return true;
573 }
574
buildOverview(ossimImageHandlerOverviewCompressionType compressionType,ossim_uint32 quality,ossimFilterResampler::ossimFilterResamplerType resampleType,bool includeFullResFlag)575 bool ossimImageHandler::buildOverview(ossimImageHandlerOverviewCompressionType compressionType,
576 ossim_uint32 quality,
577 ossimFilterResampler::ossimFilterResamplerType resampleType,
578 bool includeFullResFlag)
579 {
580 ossimFilename file = getFilenameWithThisExtension(ossimString(".ovr"));
581
582 theOverviewFile = file;
583 if(buildOverview(file, compressionType, quality, resampleType, includeFullResFlag))
584 {
585 openOverview();
586 }
587
588 return true;
589 }
590
buildAllOverviews(ossimImageHandlerOverviewCompressionType compressionType,ossim_uint32 quality,ossimFilterResampler::ossimFilterResamplerType resampleType,bool includeFullResFlag)591 bool ossimImageHandler::buildAllOverviews(ossimImageHandlerOverviewCompressionType compressionType,
592 ossim_uint32 quality,
593 ossimFilterResampler::ossimFilterResamplerType resampleType,
594 bool includeFullResFlag)
595 {
596 ossim_uint32 currentEntry = getCurrentEntry();
597 std::vector<ossim_uint32> entryList;
598 getEntryList(entryList);
599 ossim_uint32 idx = 0;
600 for(idx = 0; idx < entryList.size(); ++idx)
601 {
602 setCurrentEntry(entryList[idx]);
603 if(!buildOverview(compressionType, quality, resampleType, includeFullResFlag))
604 {
605 setCurrentEntry(currentEntry);
606 return false;
607 }
608 }
609
610 setCurrentEntry(currentEntry);
611 return true;
612 }
613
614
buildOverview(const ossimFilename & filename,ossimImageHandlerOverviewCompressionType compressionType,ossim_uint32 quality,ossimFilterResampler::ossimFilterResamplerType resampleType,bool includeFullResFlag)615 bool ossimImageHandler::buildOverview(const ossimFilename& filename,
616 ossimImageHandlerOverviewCompressionType compressionType,
617 ossim_uint32 quality,
618 ossimFilterResampler::ossimFilterResamplerType resampleType,
619 bool includeFullResFlag)
620 {
621 closeOverview();
622 if(!isOpen())
623 {
624 return false;
625 }
626
627 theOverviewFile = filename;
628 ossimTiffOverviewBuilder tiffBuilder;
629 if ( tiffBuilder.setInputSource(this) == false )
630 {
631 return false;
632 }
633
634 ossim_uint16 cType = COMPRESSION_NONE;
635 switch(compressionType)
636 {
637 case OSSIM_OVERVIEW_COMPRESSION_NONE:
638 {
639 cType = COMPRESSION_NONE;
640 break;
641 }
642 case OSSIM_OVERVIEW_COMPRESSION_JPEG:
643 {
644 cType = COMPRESSION_JPEG;
645 break;
646 }
647 case OSSIM_OVERVIEW_COMPRESSION_LZW:
648 {
649 cType = COMPRESSION_LZW;
650 break;
651 }
652 case OSSIM_OVERVIEW_COMPRESSION_DEFLATE:
653 {
654
655 cType = COMPRESSION_DEFLATE;
656 break;
657 }
658 case OSSIM_OVERVIEW_COMPRESSION_PACKBITS:
659 {
660 cType = COMPRESSION_PACKBITS;
661 break;
662 }
663 }
664 tiffBuilder.setJpegCompressionQuality(quality);
665 tiffBuilder.setCompressionType(cType);
666 tiffBuilder.setResampleType(resampleType);
667 tiffBuilder.buildOverview(filename, includeFullResFlag);
668
669 return true;
670 }
671
getImageHistogram() const672 ossimRefPtr<ossimMultiResLevelHistogram> ossimImageHandler::getImageHistogram() const
673 {
674 ossimRefPtr<ossimMultiResLevelHistogram> histogram = 0;
675 if ( isOpen() )
676 {
677 ossimFilename histoFile = getFilenameWithThisExtension(ossimString(".his"));
678 histogram = new ossimMultiResLevelHistogram();
679 if ( histogram->importHistogram(histoFile) == false )
680 {
681 histogram = 0;
682 }
683 }
684 return histogram;
685 }
686
getImageGeometry()687 ossimRefPtr<ossimImageGeometry> ossimImageHandler::getImageGeometry()
688 {
689 if ( !theGeometry )
690 {
691 //---
692 // Check factory for external geom:
693 //---
694 theGeometry = getExternalImageGeometry();
695
696 if ( !theGeometry )
697 {
698 //---
699 // WARNING:
700 // Must create/set the geometry at this point or the next call to
701 // ossimImageGeometryRegistry::extendGeometry will put us in an infinite loop
702 // as it does a recursive call back to ossimImageHandler::getImageGeometry().
703 //---
704 theGeometry = new ossimImageGeometry();
705 initImageParameters( theGeometry.get() );
706
707 //---
708 // And finally allow factories to extend the internal geometry.
709 // This allows plugins for tagged formats with tags not know in the base
710 // to extend the internal geometry.
711 //
712 // Plugins can do handler->getImageGeometry() then modify/extend.
713 //---
714 if(!ossimImageGeometryRegistry::instance()->extendGeometry( this ))
715 {
716 //---
717 // Check for internal, for geotiff, nitf and so on as last resort for getting some
718 // kind of geometry loaded
719 //---
720 theGeometry = getInternalImageGeometry();
721 initImageParameters( theGeometry.get() );
722 }
723 }
724 }
725 return theGeometry;
726 }
727
getExternalImageGeometry() const728 ossimRefPtr<ossimImageGeometry> ossimImageHandler::getExternalImageGeometry() const
729 {
730 ossimRefPtr<ossimImageGeometry> geom = 0;
731 // No geometry object has been set up yet. Check for external geometry file.
732 // Try "foo.geom" if image is "foo.tif":
733 ossimFilename filename;
734 getFilenameWithThisExt( ossimString(".geom"), filename );
735
736 if(!filename.exists())
737 {
738 // Try "foo_e0.tif" if image is "foo.tif" where "e0" is entry index.
739 filename = getFilenameWithThisExtension(ossimString(".geom"), true);
740 }
741
742 #if 0
743 /* getgetFilenameWithThisExt... methods tack on sup dir if set. drb */
744 if(!filename.exists())
745 {
746 // Try supplementary data directory for remote geometry:
747 filename = getFilenameWithThisExtension(ossimString(".geom"), false);
748 filename = theSupplementaryDirectory.dirCat(filename.file());
749 }
750 if(!filename.exists())
751 {
752 // Try supplementary data directory for remote geometry with entry index:
753 filename = getFilenameWithThisExtension(ossimString(".geom"), true);
754 filename = theSupplementaryDirectory.dirCat(filename.file());
755 }
756 #endif
757
758 if(filename.exists())
759 {
760 // Open the geom file as a KWL and initialize our geometry object:
761 filename = filename.expand();
762 ossimKeywordlist geomKwl(filename);
763
764 // Try loadState with no prefix.
765 std::string prefix = "";
766 std::string key = ossimKeywordNames::TYPE_KW;
767 std::string value = geomKwl.findKey(prefix, key);
768
769 if ( value.empty() || (value != "ossimImageGeometry") )
770 {
771 // Try with "image0." type prefix.
772 prefix += std::string("image") + ossimString::toString(getCurrentEntry()).string() +
773 std::string(".");
774 value = geomKwl.findKey(prefix, key);
775
776 if ( value.empty() || (value != "ossimImageGeometry") )
777 {
778 // Try with "image0.geometry." prefix.
779 prefix += std::string( "geometry." );
780 value = geomKwl.findKey(prefix, key);
781
782 if ( value.empty() || (value != "ossimImageGeometry") )
783 {
784 // Try with "geometry." prefix.
785 prefix = std::string( "geometry." );
786 value = geomKwl.findKey(prefix, key);
787 }
788 }
789 }
790
791 if ( value == "ossimImageGeometry" )
792 {
793 geom = new ossimImageGeometry;
794 if( !geom->loadState(geomKwl, prefix.c_str()) )
795 {
796 geom = 0;
797 }
798 }
799 }
800
801 return geom;
802 }
803
getInternalImageGeometry() const804 ossimRefPtr<ossimImageGeometry> ossimImageHandler::getInternalImageGeometry() const
805 {
806 // Default, derived classes should override.
807 ossimRefPtr<ossimImageGeometry> geom = new ossimImageGeometry();
808 return geom;
809 }
810
setImageGeometry(ossimImageGeometry * geom)811 void ossimImageHandler::setImageGeometry( ossimImageGeometry* geom)
812 {
813 theGeometry = geom;
814 }
815
saveImageGeometry() const816 void ossimImageHandler::saveImageGeometry() const
817 {
818 ossimFilename geometryFile = getFilenameWithThisExtension(ossimString(".geom"));
819 saveImageGeometry(geometryFile);
820 }
821
saveImageGeometry(const ossimFilename & geometry_file) const822 void ossimImageHandler::saveImageGeometry(const ossimFilename& geometry_file) const
823 {
824 if (theGeometry.valid())
825 {
826 ossimKeywordlist kwl;
827 theGeometry->saveState(kwl);
828 kwl.write(geometry_file.chars());
829 }
830 }
831
closeOverview()832 void ossimImageHandler::closeOverview()
833 {
834 theOverview = 0;
835 }
836
getOverview() const837 const ossimImageHandler* ossimImageHandler::getOverview() const
838 {
839 return theOverview.get();
840 }
841
hasOverviews() const842 bool ossimImageHandler::hasOverviews() const
843 {
844 return (getNumberOfDecimationLevels() > 1);
845 }
846
openOverview(const ossimFilename & overview_file)847 bool ossimImageHandler::openOverview(const ossimFilename& overview_file)
848 {
849 bool result = false;
850 if (traceDebug())
851 {
852 ossimNotify(ossimNotifyLevel_DEBUG)
853 << "ossimImageHandler::openOverview(overview_file): ...entered!";
854 }
855 closeOverview();
856
857 if (overview_file != theImageFile) // Make sure we don't open ourselves.
858 {
859 //---
860 // Get the number of level before the call to opening the overview so
861 // the overview can be told what it's starting res level is.
862 //---
863 ossim_uint32 overviewStartingResLevel = getNumberOfDecimationLevels();
864
865
866 // Try to open:
867 theOverview = ossimImageHandlerRegistry::instance()->openOverview( overview_file );
868 if (theOverview.valid())
869 {
870 result = true;
871
872 //---
873 // Set the owner in case the overview reader needs to get something
874 // from the it like min/max/null.
875 //---
876 theOverview->changeOwner(this);
877
878 // Set the starting res level of the overview.
879 theOverview->setStartingResLevel(overviewStartingResLevel);
880
881 // Capture the file name.
882 theOverviewFile = overview_file;
883
884 //---
885 // Some overview handlers cannot store what the null is. Like dted
886 // null is -32767 not default -32768 so this allows passing this to the
887 // overview reader provided it overrides setMin/Max/NullPixel value
888 // methods. (drb)
889 //---
890 const ossim_uint32 BANDS = getNumberOfOutputBands();
891 for (ossim_uint32 band = 0; band < BANDS; ++band)
892 {
893 theOverview->setMinPixelValue(band, getMinPixelValue(band));
894 theOverview->setMaxPixelValue(band, getMaxPixelValue(band));
895 theOverview->setNullPixelValue(band, getNullPixelValue(band));
896 }
897 if(m_state)
898 {
899 m_state->setOverviewState(theOverview->getState());
900 }
901 if (traceDebug())
902 {
903 ossimNotify(ossimNotifyLevel_DEBUG)
904 << "overview starting res level: " << overviewStartingResLevel
905 << "\noverview levels: "
906 << theOverview->getNumberOfDecimationLevels()
907 << "\nlevels: " << getNumberOfDecimationLevels()
908 << endl;
909 }
910
911 //---
912 // This is not really a container event; however, using for now.
913 //---
914 ossimContainerEvent event(this,
915 OSSIM_EVENT_ADD_OBJECT_ID);
916 event.setObjectList(theOverview.get());
917 fireEvent(event);
918 }
919 }
920 if (traceDebug())
921 {
922 ossimNotify(ossimNotifyLevel_DEBUG)
923 << "ossimImageHandler::openOverview(overview_file): ...leaving!";
924 }
925
926 return result;
927 }
928
openOverview()929 bool ossimImageHandler::openOverview()
930 {
931 static const char MODULE[] = "ossimImageHandler::openOverview()";
932 if (traceDebug())
933 {
934 ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
935 }
936
937 bool result = false;
938
939 closeOverview();
940
941 if(m_state)
942 {
943 // check if we have an overview state
944 std::shared_ptr<ossim::ImageHandlerState> overviewState = m_state->getOverviewState();
945 if(overviewState)
946 {
947 // check to see if the overvies state was cached
948 // to mark has checked but no overview
949 if(overviewState->getConnectionString().empty())
950 {
951 return false;
952 }
953 ossim_uint32 overviewStartingResLevel = getNumberOfDecimationLevels();
954 theOverview = ossimImageHandlerRegistry::instance()->open( overviewState );
955 if(theOverview)
956 {
957 result = true;
958 //---
959 // Set the owner in case the overview reader needs to get something
960 // from the it like min/max/null.
961 //---
962 theOverview->changeOwner(this);
963
964 // Set the starting res level of the overview.
965 theOverview->setStartingResLevel(overviewStartingResLevel);
966
967 // Capture the file name.
968 theOverviewFile = overviewState->getConnectionString();
969
970 //---
971 // Some overview handlers cannot store what the null is. Like dted
972 // null is -32767 not default -32768 so this allows passing this to the
973 // overview reader provided it overrides setMin/Max/NullPixel value
974 // methods. (drb)
975 //---
976 const ossim_uint32 BANDS = getNumberOfOutputBands();
977 for (ossim_uint32 band = 0; band < BANDS; ++band)
978 {
979 theOverview->setMinPixelValue(band, getMinPixelValue(band));
980 theOverview->setMaxPixelValue(band, getMaxPixelValue(band));
981 theOverview->setNullPixelValue(band, getNullPixelValue(band));
982 }
983 if (traceDebug())
984 {
985 ossimNotify(ossimNotifyLevel_DEBUG)
986 << "overview starting res level: " << overviewStartingResLevel
987 << "\noverview levels: "
988 << theOverview->getNumberOfDecimationLevels()
989 << "\nlevels: " << getNumberOfDecimationLevels()
990 << endl;
991 }
992
993 //---
994 // This is not really a container event; however, using for now.
995 //---
996 ossimContainerEvent event(this,
997 OSSIM_EVENT_ADD_OBJECT_ID);
998 event.setObjectList(theOverview.get());
999 fireEvent(event);
1000 return result;
1001 }
1002 }
1003 }
1004 // 1) ESH 03/2009 -- Use the overview file set e.g. using a .spec file.
1005 ossimFilename overviewFilename = getOverviewFile();
1006
1007 // ossimFilename::exists() currently does not work with s3 url's.
1008 if ( overviewFilename.empty() ) // || (overviewFilename.exists() == false) )
1009 {
1010 // 2) Generate the name from image name.
1011 overviewFilename = createDefaultOverviewFilename();
1012 }
1013
1014 // ossimFilename::exists() currently does not work with s3 url's.
1015 if ( overviewFilename.size() )
1016 {
1017 result = openOverview( overviewFilename );
1018
1019 if (traceDebug())
1020 {
1021 ossimNotify(ossimNotifyLevel_DEBUG)
1022 << (result?"Opened ":"Could not open ") << "overview: " << overviewFilename
1023 << "\n";
1024 }
1025 }
1026 if ( !result )
1027 {
1028 if (overviewFilename.empty() || (overviewFilename.exists() == false) )
1029 {
1030 // 3) For backward compatibility check if single entry and _e0.ovr
1031 overviewFilename = getFilenameWithThisExtension(ossimString(".ovr"), true);
1032
1033 if (overviewFilename.empty() || (overviewFilename.exists() == false) )
1034 {
1035 //---
1036 // 4) For overviews built with gdal.
1037 // Examples:
1038 // Single entry: foo.tif.ovr
1039 // Multi-entry: foo.tif.x.ovr where "x" == one based entry number.
1040 //
1041 // Note: Take into account a supplementary dir if any.
1042 //---
1043 if ( theSupplementaryDirectory.empty() )
1044 {
1045 overviewFilename = getFilename();
1046 }
1047 else
1048 {
1049 overviewFilename = theSupplementaryDirectory;
1050 overviewFilename = overviewFilename.dirCat( getFilename().file() );
1051
1052 }
1053
1054 if ( getNumberOfEntries() > 1 )
1055 {
1056 overviewFilename += ".";
1057 // Sample multi-entry data "one" based; hence, the + 1.
1058 overviewFilename += ossimString::toString( getCurrentEntry()+1 );
1059 }
1060 overviewFilename += ".ovr";
1061 }
1062 }
1063
1064 if ( overviewFilename.exists() )
1065 {
1066 result = openOverview( overviewFilename );
1067
1068 if (traceDebug())
1069 {
1070 ossimNotify(ossimNotifyLevel_DEBUG)
1071 << (result?"Opened ":"Could not open ") << "overview: " << overviewFilename
1072 << "\n";
1073 }
1074 }
1075 }
1076
1077 if (traceDebug())
1078 {
1079 ossimNotify(ossimNotifyLevel_DEBUG)
1080 << MODULE << " exit result: " << (result?"true":"false") << "\n";
1081 }
1082
1083 return result;
1084 }
1085
1086
writeValidImageVertices(const std::vector<ossimIpt> & vertices,const ossimFilename & file)1087 bool ossimImageHandler::writeValidImageVertices(const std::vector<ossimIpt>& vertices, const ossimFilename& file)
1088 {
1089 ossimFilename tempFile = file;
1090 if(tempFile == "")
1091 {
1092 tempFile = createDefaultValidVerticesFilename();
1093 }
1094 ossim_uint32 i = 0;
1095 ossimKeywordlist tempKwl;
1096 ossimPolygon poly(vertices);
1097
1098 poly.checkOrdering();
1099
1100 // Capture the vertices.
1101 theValidImageVertices = vertices;
1102
1103 if(poly.getOrdering() == OSSIM_COUNTERCLOCKWISE_ORDER)
1104 {
1105 std::reverse(theValidImageVertices.begin(), theValidImageVertices.end());
1106 }
1107
1108 if(theValidImageVertices.size())
1109 {
1110 for(i = 0; i < theValidImageVertices.size(); ++i)
1111 {
1112 ossimString prefix = ossimString("point") + ossimString::toString(i) + ".";
1113 tempKwl.add(prefix.c_str(),
1114 "x",
1115 theValidImageVertices[i].x,
1116 true);
1117 tempKwl.add(prefix.c_str(),
1118 "y",
1119 theValidImageVertices[i].y,
1120 true);
1121 }
1122
1123 tempKwl.write(tempFile.c_str());
1124 }
1125
1126 if ( tempFile.exists() )
1127 {
1128 return true;
1129 }
1130
1131 return false; // Write of file failed.
1132 }
1133
openValidVertices(const ossimFilename & vertices_file)1134 bool ossimImageHandler::openValidVertices(const ossimFilename& vertices_file)
1135 {
1136 return initVertices(vertices_file);
1137 }
1138
openValidVertices()1139 bool ossimImageHandler::openValidVertices()
1140 {
1141 ossimFilename vertices_file;
1142 vertices_file = theImageFile.path();
1143 vertices_file = vertices_file.dirCat(theImageFile.fileNoExtension());
1144 if(getNumberOfEntries() > 1)
1145 {
1146 vertices_file += ossimString("_vertices") + "_e" + ossimString::toString(getCurrentEntry()) + ".kwl";
1147 }
1148 else
1149 {
1150 vertices_file += "_vertices.kwl";
1151 }
1152
1153 if (traceDebug())
1154 {
1155 ossimNotify(ossimNotifyLevel_DEBUG)
1156 << "Looking for " << vertices_file
1157 << " vertices file..." << std::endl;
1158 }
1159
1160 return openValidVertices(vertices_file);
1161 }
1162
open(const ossimFilename & imageFile)1163 bool ossimImageHandler::open(const ossimFilename& imageFile)
1164 {
1165 if(isOpen())
1166 {
1167 close();
1168 }
1169
1170 setFilename(imageFile);
1171
1172 return open();
1173 }
1174
open(const ossimFilename & imageFile,ossim_uint32 entryIndex)1175 bool ossimImageHandler::open(const ossimFilename& imageFile,
1176 ossim_uint32 entryIndex)
1177 {
1178 if(isOpen())
1179 {
1180 close();
1181 }
1182 setFilename(imageFile);
1183
1184 bool result = open();
1185
1186 if(result)
1187 {
1188 return setCurrentEntry(entryIndex);
1189 }
1190
1191 return result;
1192 }
1193
open(std::shared_ptr<ossim::ImageHandlerState> state)1194 bool ossimImageHandler::open(std::shared_ptr<ossim::ImageHandlerState> state)
1195 {
1196 bool result = false;
1197 if(isOpen())
1198 {
1199 close();
1200 }
1201 setFilename(state->getConnectionString());
1202 setState(state);
1203 result = open();
1204
1205 return result;
1206 }
1207
1208
isValidRLevel(ossim_uint32 resLevel) const1209 bool ossimImageHandler::isValidRLevel(ossim_uint32 resLevel) const
1210 {
1211 bool result = false;
1212
1213 const ossim_uint32 LEVELS = getNumberOfDecimationLevels();
1214
1215 if ( !theStartingResLevel) // Not an overview.
1216 {
1217 result = (resLevel < LEVELS);
1218 }
1219 else // Used as overview.
1220 {
1221 if (resLevel >= theStartingResLevel)
1222 {
1223 //---
1224 // Adjust the res level to be zero based for this overview before
1225 // checking.
1226 //---
1227 result = ( (resLevel - theStartingResLevel) < LEVELS);
1228 }
1229 }
1230
1231 return result;
1232 }
1233
getValidImageVertices(vector<ossimIpt> & validVertices,ossimVertexOrdering ordering,ossim_uint32 resLevel) const1234 void ossimImageHandler::getValidImageVertices(vector<ossimIpt>& validVertices,
1235 ossimVertexOrdering ordering,
1236 ossim_uint32 resLevel) const
1237 {
1238 ossimDpt decimation;
1239 getDecimationFactor(resLevel, decimation);
1240 if(decimation.hasNans())
1241 {
1242 return;
1243 }
1244 if (theValidImageVertices.size() != 0)
1245 {
1246 validVertices.clear();
1247 for (ossim_uint32 i=0; i<theValidImageVertices.size(); ++i)
1248 {
1249 ossimIpt pt(ossim::round<int>(theValidImageVertices[i].x*decimation.x),
1250 ossim::round<int>(theValidImageVertices[i].y*decimation.y));
1251 validVertices.push_back(pt);
1252 }
1253
1254 if(ordering == OSSIM_COUNTERCLOCKWISE_ORDER)
1255 {
1256 std::reverse(validVertices.begin()+1, validVertices.end());
1257 }
1258 }
1259 else
1260 {
1261 // Call the base class method which will set to bounding rectangle.
1262 ossimImageSource::getValidImageVertices(validVertices, ordering, resLevel);
1263 }
1264 }
1265
close()1266 void ossimImageHandler::close()
1267 {
1268 theOverview = 0;
1269 theGeometry = 0;
1270 theValidImageVertices.clear();
1271 theDecimationFactors.clear();
1272 setState(0);
1273 }
1274
isBandSelector() const1275 bool ossimImageHandler::isBandSelector() const
1276 {
1277 return false;
1278 }
1279
setOutputBandList(const std::vector<ossim_uint32> &)1280 bool ossimImageHandler::setOutputBandList(const std::vector<ossim_uint32>& /* band_list */)
1281 {
1282 return false;
1283 }
1284
getRgbBandList(std::vector<ossim_uint32> & bandList) const1285 bool ossimImageHandler::getRgbBandList( std::vector<ossim_uint32>& bandList ) const
1286 {
1287 // Looks for "rgb_bands" key in dot omd file. E.g. "rgb_bands: (2,1,0)"
1288 return theMetaData.getRgbBands( bandList );
1289 }
1290
setOutputToInputBandList()1291 bool ossimImageHandler::setOutputToInputBandList()
1292 {
1293 bool result = false;
1294 if ( isBandSelector() )
1295 {
1296 std::vector<ossim_uint32> bandList;
1297 ossimImageSource::getOutputBandList( bandList );
1298 result = setOutputBandList( bandList );
1299 }
1300 return result;
1301 }
1302
isIdentityBandList(const std::vector<ossim_uint32> & bandList) const1303 bool ossimImageHandler::isIdentityBandList( const std::vector<ossim_uint32>& bandList ) const
1304 {
1305 bool result = false;
1306 const ossim_uint32 BANDS = (ossim_uint32)bandList.size();
1307 if ( BANDS )
1308 {
1309 std::vector<ossim_uint32> inputList;
1310 ossimImageSource::getOutputBandList( inputList ); // This populates an identity band list.
1311
1312 if ( inputList.size() == BANDS )
1313 {
1314 ossim_uint32 band = 0;
1315 while ( band < BANDS )
1316 {
1317 if ( inputList[band] != bandList[band] )
1318 {
1319 break;
1320 }
1321 ++band;
1322 }
1323 if ( band == BANDS )
1324 {
1325 result = true;
1326 }
1327 }
1328 }
1329 return result;
1330 }
1331
1332 // Protected convenience method:
setOutputBandList(const std::vector<ossim_uint32> & inBandList,std::vector<ossim_uint32> & outBandList)1333 bool ossimImageHandler::setOutputBandList(const std::vector<ossim_uint32>& inBandList,
1334 std::vector<ossim_uint32>& outBandList)
1335 {
1336 bool result = false;
1337
1338 const ossim_uint32 INPUT_BANDS = getNumberOfInputBands();
1339 const ossim_uint32 OUTPUT_BANDS = (ossim_uint32)inBandList.size();
1340
1341 if ( INPUT_BANDS && OUTPUT_BANDS )
1342 {
1343 result = true;
1344 outBandList.resize( OUTPUT_BANDS );
1345 for ( ossim_uint32 band = 0; band < OUTPUT_BANDS; ++band )
1346 {
1347 if ( inBandList[band] < INPUT_BANDS )
1348 {
1349 outBandList[band] = inBandList[band];
1350 }
1351 else // Out of range...
1352 {
1353 result = false;
1354 break;
1355 }
1356 }
1357 if ( result && theOverview.valid() )
1358 {
1359 result = theOverview->setOutputBandList( inBandList );
1360 }
1361 }
1362
1363 if ( result == false )
1364 {
1365 ossimImageSource::getOutputBandList( outBandList ); // Set to identity.
1366 }
1367
1368 return result;
1369 }
1370
isImageTiled() const1371 bool ossimImageHandler::isImageTiled() const
1372 {
1373 return (getImageTileWidth() && getImageTileHeight());
1374 }
1375
loadMetaData()1376 void ossimImageHandler::loadMetaData()
1377 {
1378
1379 if(m_state&&m_state->getMetaData())
1380 {
1381 theMetaData = *m_state->getMetaData();
1382 }
1383 else
1384 {
1385 ossimFilename filename = getFilenameWithThisExtension(ossimString(".omd"), false);
1386 theMetaData.clear();
1387
1388 std::shared_ptr<ossim::istream> instream = ossim::StreamFactoryRegistry::instance()->createIstream(filename.c_str());
1389
1390 if(!instream)
1391 {
1392 filename = getFilenameWithThisExtension(ossimString(".omd"), true);
1393 instream = ossim::StreamFactoryRegistry::instance()->createIstream(filename.c_str());
1394 }
1395
1396 if(instream)
1397 {
1398 ossimKeywordlist kwl;
1399
1400 kwl.parseStream(*instream);
1401
1402 theMetaData.loadState(kwl);
1403 }
1404 else
1405 {
1406 theMetaData.setScalarType(getOutputScalarType());
1407 }
1408 if(m_state)
1409 {
1410 m_state->setMetaData(std::make_shared<ossimImageMetaData>(theMetaData));
1411 }
1412
1413 }
1414
1415 }
1416
getMinPixelValue(ossim_uint32 band) const1417 double ossimImageHandler::getMinPixelValue(ossim_uint32 band)const
1418 {
1419 if(theMetaData.getNumberOfBands())
1420 {
1421 return theMetaData.getMinPix(band);
1422 }
1423 return ossim::defaultMin(getOutputScalarType());
1424 }
1425
getMaxPixelValue(ossim_uint32 band) const1426 double ossimImageHandler::getMaxPixelValue(ossim_uint32 band)const
1427 {
1428 if(theMetaData.getNumberOfBands())
1429 {
1430 return theMetaData.getMaxPix(band);
1431 }
1432 return ossim::defaultMax(getOutputScalarType());
1433 }
1434
getNullPixelValue(ossim_uint32 band) const1435 double ossimImageHandler::getNullPixelValue(ossim_uint32 band)const
1436 {
1437 if(theMetaData.getNumberOfBands())
1438 {
1439 return theMetaData.getNullPix(band);
1440 }
1441
1442 return ossim::defaultNull(getOutputScalarType());
1443 }
1444
setMinPixelValue(ossim_uint32 band,const ossim_float64 & pix)1445 void ossimImageHandler::setMinPixelValue(ossim_uint32 band,
1446 const ossim_float64& pix)
1447 {
1448 theMetaData.setMinPix(band, pix);
1449 }
1450
setMaxPixelValue(ossim_uint32 band,const ossim_float64 & pix)1451 void ossimImageHandler::setMaxPixelValue(ossim_uint32 band,
1452 const ossim_float64& pix)
1453 {
1454 theMetaData.setMaxPix(band, pix);
1455 }
1456
setNullPixelValue(ossim_uint32 band,const ossim_float64 & pix)1457 void ossimImageHandler::setNullPixelValue(ossim_uint32 band,
1458 const ossim_float64& pix)
1459 {
1460 theMetaData.setNullPix(band, pix);
1461 }
1462
getCurrentEntry() const1463 ossim_uint32 ossimImageHandler::getCurrentEntry()const
1464 {
1465 return 0;
1466 }
1467
setCurrentEntry(ossim_uint32 entryIdx)1468 bool ossimImageHandler::setCurrentEntry(ossim_uint32 entryIdx )
1469 {
1470 return true;
1471 }
1472
getOverviewFile() const1473 ossimFilename ossimImageHandler::getOverviewFile()const
1474 {
1475 return theOverviewFile;
1476 }
1477
getEntryList(std::vector<ossim_uint32> & entryList) const1478 void ossimImageHandler::getEntryList(std::vector<ossim_uint32>& entryList)const
1479 {
1480 entryList.push_back(0);
1481 }
1482
useEntryIndex() const1483 bool ossimImageHandler::useEntryIndex() const
1484 {
1485 bool result = false;
1486 if ( isOpen() )
1487 {
1488 std::vector<ossim_uint32> entryList;
1489 getEntryList(entryList);
1490
1491 if ( entryList.size() )
1492 {
1493 if ( (entryList.size() > 1) || (entryList[0] != 0) ) result = true;
1494 }
1495 }
1496 return result;
1497 }
1498
getNumberOfEntries() const1499 ossim_uint32 ossimImageHandler::getNumberOfEntries()const
1500 {
1501 std::vector<ossim_uint32> tempList;
1502 getEntryList(tempList);
1503
1504 return (ossim_uint32)tempList.size();
1505 }
1506
getEntryNames(std::vector<ossimString> & entryStringList) const1507 void ossimImageHandler::getEntryNames(std::vector<ossimString>& entryStringList) const
1508 {
1509 entryStringList.clear();
1510 }
1511
getEntryName(ossim_uint32 entryIdx,std::string & name) const1512 void ossimImageHandler::getEntryName( ossim_uint32 entryIdx, std::string& name ) const
1513 {
1514 name = "";
1515 std::vector<ossimString> entryNames;
1516 getEntryNames(entryNames);
1517 if (entryIdx < entryNames.size())
1518 name = entryNames[entryIdx].string();
1519 }
1520
completeOpen()1521 void ossimImageHandler::completeOpen()
1522 {
1523 if(traceDebug())
1524 {
1525 ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageHandler::completeOpen(): Entered........" << std::endl;
1526 }
1527 loadMetaData();
1528 if ( theOpenOverviewFlag )
1529 {
1530 openOverview();
1531 }
1532 establishDecimationFactors();
1533 if(traceDebug())
1534 {
1535 ossimNotify(ossimNotifyLevel_DEBUG) << "ossimImageHandler::completeOpen(): Leaving......." << std::endl;
1536 }
1537 openValidVertices();
1538 }
1539
canConnectMyInputTo(ossim_int32,const ossimConnectableObject *) const1540 bool ossimImageHandler::canConnectMyInputTo(ossim_int32 /* inputIndex */,
1541 const ossimConnectableObject* /* object */)const
1542 {
1543 return false;
1544 }
1545
hasMetaData() const1546 bool ossimImageHandler::hasMetaData()const
1547 {
1548 return theMetaData.isValid();
1549 }
1550
setFilename(const ossimFilename & filename)1551 void ossimImageHandler::setFilename(const ossimFilename& filename)
1552 {
1553 theImageFile = filename;
1554 }
1555
getFilename() const1556 const ossimFilename& ossimImageHandler::getFilename()const
1557 {
1558 return theImageFile;
1559 }
1560
setSupplementaryDirectory(const ossimFilename & dir)1561 void ossimImageHandler::setSupplementaryDirectory(const ossimFilename& dir)
1562 {
1563 if (dir.isDir())
1564 theSupplementaryDirectory = dir;
1565 else
1566 theSupplementaryDirectory = dir.path();
1567 // A change in supplementary directory presents an opportunity to find the OVR that could not be
1568 // opened previously, as well as other support data items:
1569 if (!theOverview.valid())
1570 {
1571 if (theDecimationFactors.size() > 0)
1572 {
1573 theDecimationFactors.clear();
1574 }
1575 completeOpen();
1576 }
1577 }
1578
getSupplementaryDirectory() const1579 const ossimFilename& ossimImageHandler::getSupplementaryDirectory()const
1580 {
1581 return theSupplementaryDirectory;
1582 }
1583
setProperty(ossimRefPtr<ossimProperty> property)1584 void ossimImageHandler::setProperty(ossimRefPtr<ossimProperty> property)
1585 {
1586 if ( property.valid() )
1587 {
1588 if(property->getName() == ossimKeywordNames::ENTRY_KW)
1589 {
1590 setCurrentEntry(property->valueToString().toUInt32());
1591 }
1592 else if ( property->getName() == OPEN_OVERVIEW_FLAG_KW )
1593 {
1594 setOpenOverviewFlag( property->valueToString().toBool() );
1595 }
1596 else
1597 {
1598 ossimImageSource::setProperty(property);
1599 }
1600 }
1601 }
1602
getProperty(const ossimString & name) const1603 ossimRefPtr<ossimProperty> ossimImageHandler::getProperty(const ossimString& name)const
1604 {
1605
1606 if(name == ossimKeywordNames::ENTRY_KW)
1607 {
1608 std::vector<ossim_uint32> entryList;
1609 getEntryList(entryList);
1610
1611 ossimStringProperty* stringProperty = new ossimStringProperty(name,
1612 ossimString::toString(getCurrentEntry()));
1613 ossim_uint32 idx = 0;
1614 for(idx = 0; idx < entryList.size(); ++idx)
1615 {
1616 stringProperty->addConstraint(ossimString::toString(entryList[idx]));
1617 }
1618 stringProperty->setFullRefreshBit();
1619 stringProperty->setEditableFlag(false);
1620
1621 return stringProperty;
1622 }
1623 else if(name == ossimKeywordNames::NUMBER_SAMPLES_KW)
1624 {
1625 ossimNumericProperty* prop = new ossimNumericProperty(name, ossimString::toString(getNumberOfSamples()));
1626 prop->setReadOnlyFlag(true);
1627
1628 return prop;
1629 }
1630 else if(name == ossimKeywordNames::NUMBER_LINES_KW)
1631 {
1632 ossimNumericProperty* prop = new ossimNumericProperty(name, ossimString::toString(getNumberOfLines()));
1633 prop->setReadOnlyFlag(true);
1634
1635 return prop;
1636 }
1637 else if(name == ossimKeywordNames::NUMBER_BANDS_KW)
1638 {
1639 ossimNumericProperty* prop = new ossimNumericProperty(name, ossimString::toString(getNumberOfInputBands()));
1640 prop->setReadOnlyFlag(true);
1641
1642 return prop;
1643 }
1644 else if(name == ossimKeywordNames::NUMBER_REDUCED_RES_SETS_KW)
1645 {
1646 ossimNumericProperty* prop = new ossimNumericProperty(name, ossimString::toString(getNumberOfDecimationLevels()));
1647 prop->setReadOnlyFlag(true);
1648
1649 return prop;
1650 }
1651 else if(name == ossimKeywordNames::SCALAR_TYPE_KW)
1652 {
1653 ossimStringProperty* prop = new ossimStringProperty(name, ossimScalarTypeLut::instance()->getEntryString(getOutputScalarType()));
1654 prop->setReadOnlyFlag(true);
1655
1656 return prop;
1657 }
1658 else if(name == "histogram_filename")
1659 {
1660 ossimFilenameProperty* filenameProp =
1661 new ossimFilenameProperty(name, createDefaultHistogramFilename());
1662
1663 filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
1664 filenameProp->setCacheRefreshBit();
1665
1666 return filenameProp;
1667
1668 }
1669 else if(name == "geometry_filename")
1670 {
1671 ossimFilenameProperty* filenameProp =
1672 new ossimFilenameProperty(name, createDefaultGeometryFilename());
1673
1674 filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
1675 filenameProp->setCacheRefreshBit();
1676
1677 return filenameProp;
1678
1679 }
1680 else if(name == "valid_vertices_filename")
1681 {
1682 ossimFilenameProperty* filenameProp =
1683 new ossimFilenameProperty(name, createDefaultValidVerticesFilename());
1684
1685 filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
1686 filenameProp->setCacheRefreshBit();
1687
1688 return filenameProp;
1689 }
1690 else if(name == "metadata_filename")
1691 {
1692 ossimFilenameProperty* filenameProp =
1693 new ossimFilenameProperty(name, createDefaultMetadataFilename());
1694
1695 filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
1696 filenameProp->setCacheRefreshBit();
1697
1698 return filenameProp;
1699 }
1700 else if(name == "overview_filename")
1701 {
1702 ossimFilenameProperty* filenameProp =
1703 new ossimFilenameProperty(name, createDefaultOverviewFilename());
1704
1705 filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
1706 filenameProp->setCacheRefreshBit();
1707
1708 return filenameProp;
1709 }
1710 else if(name == "filename")
1711 {
1712 ossimFilenameProperty* filenameProp =
1713 new ossimFilenameProperty(name, getFilename());
1714
1715 filenameProp->setIoType(ossimFilenameProperty::ossimFilenamePropertyIoType_INPUT);
1716 filenameProp->setFullRefreshBit();
1717
1718 return filenameProp;
1719 }
1720 else if ( name == OPEN_OVERVIEW_FLAG_KW)
1721 {
1722 ossimRefPtr<ossimProperty> result =
1723 new ossimBooleanProperty(ossimString(OPEN_OVERVIEW_FLAG_KW), theOpenOverviewFlag);
1724 return result;
1725 }
1726
1727 return ossimImageSource::getProperty(name);
1728 }
1729
getPropertyNames(std::vector<ossimString> & propertyNames) const1730 void ossimImageHandler::getPropertyNames(std::vector<ossimString>& propertyNames)const
1731 {
1732 ossimImageSource::getPropertyNames(propertyNames);
1733 propertyNames.push_back(ossimKeywordNames::ENTRY_KW);
1734 propertyNames.push_back(ossimKeywordNames::NUMBER_SAMPLES_KW);
1735 propertyNames.push_back(ossimKeywordNames::NUMBER_LINES_KW);
1736 propertyNames.push_back(ossimKeywordNames::NUMBER_BANDS_KW);
1737 propertyNames.push_back(ossimKeywordNames::NUMBER_REDUCED_RES_SETS_KW);
1738 propertyNames.push_back(ossimKeywordNames::SCALAR_TYPE_KW);
1739 propertyNames.push_back(OPEN_OVERVIEW_FLAG_KW);
1740 }
1741
getFilenameWithThisExtension(const ossimString & ext,bool set_e0_prefix) const1742 ossimFilename ossimImageHandler::getFilenameWithThisExtension(
1743 const ossimString& ext,
1744 bool set_e0_prefix) const
1745 {
1746 // Get the image file.
1747 ossimFilename f = getFilename();
1748
1749 getFilenameWithNoExtension( f );
1750
1751 if (set_e0_prefix || (getNumberOfEntries() > 1))
1752 {
1753 f += "_e";
1754 f += ossimString::toString(getCurrentEntry());
1755 }
1756
1757 if (ext.size())
1758 {
1759 if (ext.string()[0] != '.')
1760 {
1761 f += ".";
1762 }
1763 f += ext;
1764 }
1765 return f;
1766 }
1767
getFilenameWithThisExt(const ossimString & ext,ossimFilename & f) const1768 void ossimImageHandler::getFilenameWithThisExt( const ossimString& ext,
1769 ossimFilename& f ) const
1770 {
1771 // Get the image file.
1772 f = getFilename();
1773
1774 getFilenameWithNoExtension( f );
1775
1776 if (ext.size())
1777 {
1778 if (ext.string()[0] != '.')
1779 {
1780 f += ".";
1781 }
1782 f += ext;
1783 }
1784 }
1785
getFilenameWithNoExtension(ossimFilename & f) const1786 void ossimImageHandler::getFilenameWithNoExtension( ossimFilename& f ) const
1787 {
1788 //---
1789 // If the supplementary directory is set, find the extension at that
1790 // location instead of at the default.
1791 //---
1792 if ( theSupplementaryDirectory.size() )
1793 {
1794 ossimString drivePart;
1795 ossimString pathPart;
1796 ossimString filePart;
1797 ossimString extPart;
1798
1799 f.split(drivePart,
1800 pathPart,
1801 filePart,
1802 extPart);
1803
1804 ossimFilename newDrivePart = theSupplementaryDirectory.drive();
1805 ossimFilename newPathPart = theSupplementaryDirectory.after(newDrivePart);
1806
1807 f.merge( newDrivePart, newPathPart, filePart, extPart );
1808 }
1809
1810 // Wipe out the extension.
1811 f.setExtension("");
1812 }
1813
getOverviewTile(ossim_uint32 resLevel,ossimImageData * result)1814 bool ossimImageHandler::getOverviewTile(ossim_uint32 resLevel,
1815 ossimImageData* result)
1816 {
1817 bool status = false;
1818
1819 if (theOverview.valid())
1820 {
1821 if (theOverview->isValidRLevel(resLevel) && result &&
1822 (result->getNumberOfBands() == getNumberOfOutputBands()) )
1823 {
1824 status = theOverview->getTile(result, resLevel);
1825 }
1826 }
1827
1828 return status;
1829 }
1830
getLut() const1831 ossimRefPtr<ossimNBandLutDataObject> ossimImageHandler::getLut()const
1832 {
1833 return theLut;
1834 }
1835
hasLut() const1836 bool ossimImageHandler::hasLut() const
1837 {
1838 return theLut.valid();
1839 }
1840
createDefaultOverviewFilename() const1841 ossimFilename ossimImageHandler::createDefaultOverviewFilename() const
1842 {
1843 return getFilenameWithThisExtension("ovr");
1844 }
1845
createDefaultGeometryFilename() const1846 ossimFilename ossimImageHandler::createDefaultGeometryFilename() const
1847 {
1848 return getFilenameWithThisExtension("geom");
1849 }
1850
createDefaultMetadataFilename() const1851 ossimFilename ossimImageHandler::createDefaultMetadataFilename() const
1852 {
1853 return getFilenameWithThisExtension("omd");
1854 }
1855
createDefaultHistogramFilename() const1856 ossimFilename ossimImageHandler::createDefaultHistogramFilename() const
1857 {
1858 return getFilenameWithThisExtension("his");
1859 }
1860
createDefaultValidVerticesFilename() const1861 ossimFilename ossimImageHandler::createDefaultValidVerticesFilename() const
1862 {
1863 ossimFilename result;
1864
1865 result = theImageFile.path();
1866 result = result.dirCat(theImageFile.fileNoExtension());
1867 result += "_vertices";
1868 if(getNumberOfEntries() > 1)
1869 {
1870 result += "_e";
1871 result += ossimString::toString(getCurrentEntry());
1872 }
1873 result += ".kwl";
1874
1875 return result;
1876 }
1877
getStartingResLevel() const1878 ossim_uint32 ossimImageHandler::getStartingResLevel() const
1879 {
1880 return theStartingResLevel;
1881 }
1882
setStartingResLevel(ossim_uint32 level)1883 void ossimImageHandler::setStartingResLevel(ossim_uint32 level)
1884 {
1885 theStartingResLevel = level;
1886 }
1887
getOpenOverviewFlag() const1888 bool ossimImageHandler::getOpenOverviewFlag() const
1889 {
1890 return theOpenOverviewFlag;
1891 }
1892
setOpenOverviewFlag(bool flag)1893 void ossimImageHandler::setOpenOverviewFlag(bool flag)
1894 {
1895 theOpenOverviewFlag = flag;
1896
1897 // If false close overview if open??? (drb)
1898 }
1899
initImageParameters(ossimImageGeometry * geom) const1900 void ossimImageHandler::initImageParameters(ossimImageGeometry* geom) const
1901 {
1902 if ( geom )
1903 {
1904 // Set decimation levels
1905 ossim_uint32 num_levels = getNumberOfDecimationLevels();
1906 if ((num_levels > 0) && (num_levels != geom->getNumberOfDecimations()))
1907 {
1908 geom->setDiscreteDecimation(theDecimationFactors);
1909 }
1910
1911 // Set image size.
1912 if(geom->getImageSize().hasNans())
1913 {
1914 ossimIrect rect = getBoundingRect();
1915 geom->setImageSize(ossimIpt(rect.width(), rect.height()));
1916 }
1917 }
1918 }
1919