OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGdalTileSource.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts
6 //
7 // Description:
8 //
9 // Contains class implementaiton for the class "ossimGdalTileSource".
10 //
11 //*******************************************************************
12 // $Id: ossimGdalTileSource.cpp 23191 2015-03-14 15:01:39Z dburken $
13 
14 #include "ossimGdalTileSource.h"
15 #include "ossimGdalType.h"
16 #include "ossimOgcWktTranslator.h"
18 #include <ossim/base/ossimCommon.h>
19 #include <ossim/base/ossimDpt.h>
22 #include <ossim/base/ossimGrect.h>
23 #include <ossim/base/ossimIpt.h>
26 #include <ossim/base/ossimNotify.h>
30 #include <ossim/base/ossimTrace.h>
44 
45 #include <gdal_priv.h>
46 #include <cpl_string.h>
47 
48 #include <sstream>
49 
50 RTTI_DEF1(ossimGdalTileSource, "ossimGdalTileSource", ossimImageHandler)
51 
52 static ossimOgcWktTranslator wktTranslator;
53 static ossimTrace traceDebug("ossimGdalTileSource:debug");
54 
55 static const char DRIVER_SHORT_NAME_KW[] = "driver_short_name";
56 static const char PRESERVE_PALETTE_KW[] = "preserve_palette";
57 
58 
59 using namespace ossim;
60 
61 //*******************************************************************
62 // Public Constructor:
63 //*******************************************************************
65  :
67  theDataset(0),
68  theTile(0),
69  theSingleBandTile(0),
70  theImageBound(),
71  theMinPixValues(0),
72  theMaxPixValues(0),
73  theNullPixValues(0),
74  theEntryNumberToRender(0),
75  theSubDatasets(),
76  theIsComplexFlag(false),
77  theAlphaChannelFlag(false),
78  m_preservePaletteIndexesFlag(false),
79  m_outputBandList(0),
80  m_isBlocked(false)
81 {
82  // Pick up any default settings from preference file if set.
83  getDefaults();
84 }
85 
86 //*******************************************************************
87 // Destructor:
88 //*******************************************************************
90 {
91  close();
92 }
93 
95 {
96  if(theDataset)
97  {
98  GDALClose(theDataset);
99  theDataset = 0;
100  }
101 
102  theTile = 0;
103  theSingleBandTile = 0;
104 
105  if(theMinPixValues)
106  {
107  delete [] theMinPixValues;
108  theMinPixValues = 0;
109  }
110  if(theMaxPixValues)
111  {
112  delete [] theMaxPixValues;
113  theMaxPixValues = 0;
114  }
115  if(theNullPixValues)
116  {
117  delete [] theNullPixValues;
118  theNullPixValues = 0;
119  }
121 
123  theAlphaChannelFlag = false;
124  theIsComplexFlag = false;
125 }
126 
127 //*******************************************************************
128 // Public Method:
129 //*******************************************************************
131 {
132 
133  if(traceDebug())
134  {
136  << "ossimGdalTileSource::open() DEBUG: entered ..."
137  << std::endl;
138  }
139 
140  if(isOpen())
141  {
142  close();
143  }
144  ossimString driverNameTmp;
145 
146  if (theSubDatasets.size() == 0)
147  {
148  // Note: Cannot feed GDALOpen a NULL string!
149  if (theImageFile.size())
150  {
151  theDataset = GDALOpen(theImageFile.c_str(), GA_ReadOnly);
152  if( theDataset == 0 )
153  {
154  return false;
155  }
156  }
157  else
158  {
159  return false;
160  }
161 
162  if (traceDebug())
163  {
165  << "ossimGdalTileSource::open DEBUG:"
166  << "\nOpened image: "
167  << theImageFile.c_str()
168  << std::endl;
169  }
170 
171  // Check if it is nitf data for deciding whether or not open each sub-dataset
172  //This will be removed eventually when ossim can handle 2GB nitf file.
173  GDALDriverH driverTmp = GDALGetDatasetDriver(theDataset);
174  bool isNtif = false;
175  if (driverTmp != 0)
176  {
177  driverNameTmp = ossimString(GDALGetDriverShortName(driverTmp));
178  driverNameTmp = driverNameTmp.upcase();
179  if (driverNameTmp == "NITF")
180  {
181  isNtif = true;
182  }
183  }
184 
185  // Check for sub data sets...
186  char** papszMetadata = GDALGetMetadata( theDataset, "SUBDATASETS" );
187  if( CSLCount(papszMetadata) > 0 )
188  {
189  theSubDatasets.clear();
190 
191  for( int i = 0; papszMetadata[i] != 0; ++i )
192  {
193  ossimString os = papszMetadata[i];
194  if (os.contains("_NAME="))
195  {
196  //Sub sets have already been set. Open each sub-dataset really slow down the process
197  //specially for hdf data which sometimes has over 100 sub-datasets. Since following code
198  //only for ntif cloud checking, so only open each sub-dataset here if the dataset is
199  //nitf. This will be removed eventually when ossim can handle 2GB nitf file.
200  //Otherwise open a sub-dataset when setCurrentEntry() gets called.
201  if (isNtif)
202  {
203  GDALDatasetH subDataset = GDALOpen(filterSubDatasetsString(os),
204  GA_ReadOnly);
205  if ( subDataset != 0 )
206  {
207  // ESH 12/2008: Ticket #482
208  // "Worldview ingest should ignore subimages when NITF_ICAT=CLOUD"
209  // Hack: Ignore NITF subimages marked as cloud layers.
210  ossimString nitfIcatTag( GDALGetMetadataItem( subDataset, "NITF_ICAT", "" ) );
211  if ( nitfIcatTag.contains("CLOUD") == false )
212  {
214  }
215  }
216  GDALClose(subDataset);
217  }
218  else
219  {
221  }
222  }
223  }
224 
225  if (traceDebug())
226  {
228  << "ossimGdalTileSource::open DEBUG:" << std::endl;
229  for (ossim_uint32 idx = 0; idx < theSubDatasets.size(); ++idx)
230  {
232  << "Sub_data_set[" << idx << "] "
233  << theSubDatasets[idx] << std::endl;
234  }
235  }
236 
237  //---
238  // Have multiple entries. We're going to default to open the first
239  // entry like cidcadrg.
240  //---
241  close();
242 
244  GA_ReadOnly);
245  if (theDataset == 0)
246  {
247  if(traceDebug())
248  {
249  ossimNotify(ossimNotifyLevel_WARN) << "Could not open sub dataset = " << theSubDatasets[theEntryNumberToRender] << "\n";
250  }
251  return false;
252  }
253  if (traceDebug())
254  {
256  << "ossimGdalTileSource::open DEBUG:"
257  << "\nOpened sub data set: "
259  << std::endl;
260  }
261 
262  } // End of has subsets block.
263 
264  } // End of "if (theSubdatasets.size() == 0)"
265  else
266  {
267  // Sub sets have already been set.
269  GA_ReadOnly);
270  if (theDataset == 0)
271  {
272  return false;
273  }
274 
275  if (traceDebug())
276  {
278  << "ossimGdalTileSource::open DEBUG:"
279  << "\nOpened sub data set: "
281  << std::endl;
282  }
283  }
284 
285  // Set the driver.
286  theDriver = GDALGetDatasetDriver( theDataset );
287 
288  if(!theDriver) return false;
289 
290  if(traceDebug())
291  {
293  << "ossimGdalTileSource::open Driver: "
294  << GDALGetDriverShortName( theDriver )
295  << "/" << GDALGetDriverLongName( theDriver ) << std::endl;
296  }
297 
298  theGdtType = GDT_Byte;
299  theOutputGdtType = GDT_Byte;
300 
301  if(getNumberOfInputBands() < 1 )
302  {
303  if(CSLCount(GDALGetMetadata(theDataset, "SUBDATASETS")))
304  {
306  << "ossimGdalTileSource::open WARNING:"
307  << "\nHas multiple sub datasets and need to set the data before"
308  << " we can get to the bands" << std::endl;
309  }
310 
311  close();
313  << "ossimGdalTileSource::open WARNING:"
314  << "\nNo band data present in ossimGdalTileSource::open" << std::endl;
315  return false;
316  }
317 
318  ossim_int32 i = 0;
319  GDALRasterBandH bBand = GDALGetRasterBand( theDataset, 1 );
320  theGdtType = GDALGetRasterDataType(bBand);
321 
322  // Establish raster-pixel alignment type:
324  char** papszMetadata = GDALGetMetadata( bBand, NULL );
325  if (CSLCount(papszMetadata) > 0)
326  {
327  for(int i = 0; papszMetadata[i] != NULL; i++ )
328  {
329  ossimString metaStr = papszMetadata[i];
330  if (metaStr.contains("AREA_OR_POINT"))
331  {
332  ossimString pixel_is_point_or_area = metaStr.split("=")[1];
333  pixel_is_point_or_area.downcase();
334  if (pixel_is_point_or_area.contains("area"))
336  break;
337  }
338  }
339  }
340 
341  if(!isIndexed(1))
342  {
343  for(i = 0; i < GDALGetRasterCount(theDataset); ++i)
344  {
345  if(theGdtType != GDALGetRasterDataType(GDALGetRasterBand( theDataset,
346  i+1 )))
347  {
349  << "ossimGdalTileSource::open WARNING"
350  << "\nWe currently do not support different scalar type bands."
351  << std::endl;
352  close();
353  return false;
354  }
355 // if(GDALGetRasterColorInterpretation(GDALGetRasterBand(
356 // theDataset,
357 // i+1 )) == GCI_PaletteIndex)
358 // {
359 // ossimNotify(ossimNotifyLevel_WARN)
360 // << "ossimGdalTileSource::open WARNING"
361 // << "Index palette bands are not supported." << endl;
362 // close();
363 // return false;
364 // }
365  }
366  }
368  switch(theGdtType)
369  {
370  case GDT_CInt16:
371  {
372 // theOutputGdtType = GDT_Int16;
373  theIsComplexFlag = true;
374  break;
375  }
376  case GDT_CInt32:
377  {
378 // theOutputGdtType = GDT_Int32;
379  theIsComplexFlag = true;
380  break;
381  }
382  case GDT_CFloat32:
383  {
384 // theOutputGdtType = GDT_Float32;
385  theIsComplexFlag = true;
386  break;
387  }
388  case GDT_CFloat64:
389  {
390 // theOutputGdtType = GDT_Float64;
391  theIsComplexFlag = true;
392  break;
393  }
394  default:
395  {
396  theIsComplexFlag = false;
397  break;
398  }
399  }
400 
401  if((ossimString(GDALGetDriverShortName( theDriver )) == "PNG")&&
402  (getNumberOfInputBands() == 4))
403  {
404  theAlphaChannelFlag = true;
405  }
406  populateLut();
407  computeMinMax();
408  completeOpen();
409 
412 
414  {
415  theTile->setIndexedFlag(true);
417  }
418 
419  theTile->initialize();
421 
422  theGdalBuffer.resize(0);
423  if(theIsComplexFlag)
424  {
426  }
427 
429  ,0
430  ,GDALGetRasterXSize(theDataset)-1
431  ,GDALGetRasterYSize(theDataset)-1);
432 
433  if(traceDebug())
434  {
435 
437  << "ossimGdalTileSoruce::open\n"
438  << "data type = " << theTile->getScalarType() << std::endl;
439 
440  for(ossim_uint32 i = 0; i < getNumberOfInputBands(); ++i)
441  {
443  << "min pix " << i << ":" << getMinPixelValue(i)
444  << "\nmax pix " << i << ":" << getMaxPixelValue(i)
445  << "\nnull pix " << i << ":" << getNullPixelValue(i) << std::endl;
446  }
448  << "theTile:\n" << *theTile
449  << "theSingleBandTile:\n" << *theSingleBandTile
450  << std::endl;
451  }
452 
453  int xSize=0, ySize=0;
454  GDALGetBlockSize(GDALGetRasterBand( theDataset, 1 ),
455  &xSize,
456  &ySize);
457  // Garrett:
458  // For now, I will just enable te block reads with the JPIP and JP2 tyope drivers
459  // if it's a block encoded image
460  //
461  //
462  if(driverNameTmp.contains("JPIP")||driverNameTmp.contains("JP2"))
463  {
464  m_isBlocked = ((xSize > 1)&&(ySize > 1));
465  }
466  else
467  {
468  m_isBlocked = false;
469  }
470  if(m_isBlocked)
471  {
472  setRlevelCache();
473  }
474  return true;
475 }
476 
478  ossim_uint32 resLevel)
479 {
480  // This tile source bypassed, or invalid res level, return a blank tile.
481  if (!isSourceEnabled() || !theDataset)
482  {
484  }
485 
486  // Check for intersect.
487  ossimIrect imageBound = getBoundingRect(resLevel);
488  if(!tileRect.intersects(imageBound))
489  {
490  theTile->setImageRectangle(tileRect);
491  theTile->makeBlank();
492  return theTile;
493  }
494 
495  if(m_isBlocked)
496  {
497  return getTileBlockRead(tileRect, resLevel);
498  }
499  // Check for overview.
500  if(resLevel)
501  {
503  {
504  // No mechanism for this coded for reduce resolution levels.
505  throw ossimException( std::string("ossimGdalTileSource::getTile ERROR: Accessing reduced resolution level with the preservePaletteIndexesFlag set!") );
506  }
507 
508  if(theOverview.valid() && theOverview->isValidRLevel(resLevel))
509  {
510  ossimRefPtr<ossimImageData> tileData = theOverview->getTile(tileRect, resLevel);
511  tileData->setScalarType(getOutputScalarType());
512  return tileData;
513  }
514 
515 #if 1
516  //---
517  // Note: This code was shut off since we currently don't utilize gdal overviews.
518  // ossimGdalTileSource::getNumberOfDecimationLevels has been fixed accordingly.
519  // drb - 20110503
520  //---
521  else if(GDALGetRasterCount(theDataset))
522  {
523  GDALRasterBandH band = GDALGetRasterBand(theDataset, 1);
524  if(static_cast<int>(resLevel) > GDALGetOverviewCount(band))
525  {
527  }
528  }
529 #endif
530  }
531 
532  // Set the rectangle of the tile.
533  theTile->setImageRectangle(tileRect);
534 
535  // Compute clip rectangle with respect to the image bounds.
536  ossimIrect clipRect = tileRect.clipToRect(imageBound);
537 
539 
540  if (tileRect.completely_within(clipRect) == false)
541  {
542  // Not filling whole tile so blank it out first.
543  theTile->makeBlank();
544  }
545 
546  // Always blank the single band tile.
548 
549  ossim_uint32 anOssimBandIndex = 0;
550  ossim_uint32 aGdalBandIndex = 1;
551 
552  ossim_uint32 rasterCount = GDALGetRasterCount(theDataset);
553  if (m_outputBandList.size() > 0)
554  {
555  rasterCount = (ossim_uint32) m_outputBandList.size();
556  }
557 
558  ossim_uint32 outputBandIndex = 0;
559  for(ossim_uint32 aBandIndex =1; aBandIndex <= rasterCount; ++aBandIndex)
560  {
561  if (m_outputBandList.size() > 0)
562  {
563  aGdalBandIndex = m_outputBandList[outputBandIndex] + 1;
564  outputBandIndex++;
565  }
566  else
567  {
568  aGdalBandIndex = aBandIndex;
569  }
570  GDALRasterBandH aBand = resolveRasterBand( resLevel, aGdalBandIndex );
571  if ( aBand )
572  {
573  bool bReadSuccess;
574  if(!theIsComplexFlag)
575  {
576  bReadSuccess = (GDALRasterIO(aBand
577  , GF_Read
578  , clipRect.ul().x
579  , clipRect.ul().y
580  , clipRect.width()
581  , clipRect.height()
583  , clipRect.width()
584  , clipRect.height()
586  , 0
587  , 0 ) == CE_None) ? true : false;
588 
589  if ( bReadSuccess == true )
590  {
591  if(isIndexed(aGdalBandIndex))
592  {
593  if(isIndexTo3Band(aGdalBandIndex))
594  {
596  {
598  clipRect, anOssimBandIndex);
599  anOssimBandIndex += 1;
600  }
601  else
602  {
603  loadIndexTo3BandTile(clipRect, aGdalBandIndex, anOssimBandIndex);
604  anOssimBandIndex+=3;
605  }
606  }
607  else if(isIndexTo1Band(aGdalBandIndex))
608  {
609  // ??? Ignoring (drb)
610  anOssimBandIndex += 1;
611  }
612  }
613  else
614  {
615  if(theAlphaChannelFlag&&(aGdalBandIndex==rasterCount))
616  {
619  clipRect,
620  false);
621  }
622  else
623  {
624  // Note fix rectangle to represent theBuffer's rect in image space.
626  , clipRect
627  , anOssimBandIndex);
628  ++anOssimBandIndex;
629  }
630  }
631  }
632  else
633  {
634  ++anOssimBandIndex;
635  }
636  }
637  else // matches if(!theIsComplexFlag){}
638  {
639  bReadSuccess = (GDALRasterIO(aBand
640  , GF_Read
641  , clipRect.ul().x
642  , clipRect.ul().y
643  , clipRect.width()
644  , clipRect.height()
645  , &theGdalBuffer.front()
646  , clipRect.width()
647  , clipRect.height()
649  , 0
650  , 0 ) == CE_None) ? true : false;
651  if ( bReadSuccess == true )
652  {
654  ossim_uint32 byteSize2 = byteSize*2;
655  ossim_uint8* complexBufPtr = (ossim_uint8*)(&theGdalBuffer.front()); // start at first real part
656  ossim_uint8* outBufPtr = (ossim_uint8*)(theSingleBandTile->getBuf());
658  ossim_uint32 idx = 0;
659  for(idx = 0; idx < idxMax; ++idx)
660  {
661  memcpy(outBufPtr, complexBufPtr, byteSize);
662  complexBufPtr += byteSize2;
663  outBufPtr += byteSize;
664  }
666  , clipRect
667  , anOssimBandIndex);
668  ++anOssimBandIndex;
669  complexBufPtr = (ossim_uint8*)(&theGdalBuffer.front()) + byteSize; // start at first imaginary part
670  outBufPtr = (ossim_uint8*)(theSingleBandTile->getBuf());
671  for(idx = 0; idx < idxMax; ++idx)
672  {
673  memcpy(outBufPtr, complexBufPtr, byteSize);
674  complexBufPtr += byteSize2;
675  outBufPtr += byteSize;
676  }
678  , clipRect
679  , anOssimBandIndex);
680  ++anOssimBandIndex;
681  }
682  else
683  {
684  anOssimBandIndex += 2;
685  }
686  }
687  }
688  }
689 
690  theTile->validate();
691  return theTile;
692 }
693 
695  ossim_uint32 resLevel)
696 {
698  ossimIrect imageBound = getBoundingRect(resLevel);
699  theTile->setImageRectangle(tileRect);
700 
701  // Compute clip rectangle with respect to the image bounds.
702  ossimIrect clipRect = tileRect.clipToRect(imageBound);
703 
704  if (tileRect.completely_within(clipRect) == false)
705  {
706  // Not filling whole tile so blank it out first.
707  theTile->makeBlank();
708  }
709  if(m_isBlocked)
710  {
711  int xSize=0, ySize=0;
712  GDALGetBlockSize(resolveRasterBand( resLevel, 1 ),
713  &xSize,
714  &ySize);
715  ossimIrect blockRect = clipRect;
716  blockRect.stretchToTileBoundary(ossimIpt(xSize, ySize));
717  blockRect = blockRect.clipToRect(getBoundingRect(resLevel));
718 
719  // we need to cache here
720  //
721  ossim_int64 x = blockRect.ul().x;
722  ossim_int64 y = blockRect.ul().y;
723  ossim_int64 maxx = blockRect.lr().x;
724  ossim_int64 maxy = blockRect.lr().y;
725  ossim_uint32 aGdalBandIndex = 1;
726  ossim_uint32 rasterCount = GDALGetRasterCount(theDataset);
727  if (m_outputBandList.size() > 0)
728  {
729  rasterCount = m_outputBandList.size();
730  }
731 
732  ossim_uint32 outputBandIndex = 0;
733  for(;x < maxx;x+=xSize)
734  {
735  for(;y < maxy;y+=ySize)
736  {
737  ossimIpt origin(x,y);
738 
740 
741  if(!cacheTile.valid())
742  {
743  ossimIrect rect(origin.x,origin.y,origin.x+xSize-1, origin.y+ySize-1);
745  ossimIrect validRect = rect.clipToRect(imageBound);
746  cacheTile = ossimImageDataFactory::instance()->create(this, this);
747  cacheTile->setImageRectangle(validRect);
748  cacheTile->initialize();
749  for(ossim_uint32 aBandIndex =1; aBandIndex <= rasterCount; ++aBandIndex)
750  {
751  if (m_outputBandList.size() > 0)
752  {
753  aGdalBandIndex = m_outputBandList[outputBandIndex] + 1;
754  outputBandIndex++;
755  }
756  else
757  {
758  aGdalBandIndex = aBandIndex;
759  }
760  GDALRasterBandH aBand = resolveRasterBand( resLevel, aGdalBandIndex );
761  if ( aBand )
762  {
763  try{
764 
765  bool bReadSuccess = (GDALReadBlock(aBand, x/xSize, y/ySize, theSingleBandTile->getBuf() )== CE_None) ? true : false;
766  if(bReadSuccess)
767  {
768  cacheTile->loadBand(theSingleBandTile->getBuf(), theSingleBandTile->getImageRectangle(), aBandIndex-1);
769  }
770  }
771  catch(...)
772  {
773  }
774  }
775  }
776  cacheTile->validate();
777  ossimAppFixedTileCache::instance()->addTile(m_rlevelBlockCache[resLevel], cacheTile.get(), false);
778  }
779  theTile->loadTile(cacheTile->getBuf(), cacheTile->getImageRectangle(), OSSIM_BSQ);
780  result = theTile;
781  }
782  }
783  }
784  if(result.valid()) result->validate();
785 
786  return result;
787 }
788 
789 //*******************************************************************
790 // Public Method:
791 //*******************************************************************
793 {
794  if(isOpen())
795  {
796  if (m_outputBandList.size() > 0)
797  {
798  return (ossim_uint32) m_outputBandList.size();
799  }
800 
801  if(isIndexed(1))
802  {
803  return getIndexBandOutputNumber(1);
804  }
805 
806  if(!theIsComplexFlag)
807  {
808  return GDALGetRasterCount(theDataset);
809  }
810  return GDALGetRasterCount(theDataset)*2;
811  }
812  return 0;
813 }
814 
821 {
822  ossim_uint32 result = 0;
823  if( isIndexTo3Band() )
824  {
826  {
827  result = 1; // Passing palette indexes not expanded rgb values.
828  }
829  else
830  {
831  result = 3;
832  }
833  }
834  else if (theAlphaChannelFlag)
835  {
836  result = 3;
837  }
838  else
839  {
840  // the number of outputs will be the same as the number of inputs
841  result = getNumberOfInputBands();
842  }
843  return result;
844 }
845 
846 //*******************************************************************
847 // Public Method:
848 //*******************************************************************
850 {
851 
852  ossim_uint32 result = 0;
853  if ( isOpen() && isValidRLevel(reduced_res_level) )
854  {
855  if(theOverview.valid() && theOverview->isValidRLevel(reduced_res_level))
856  {
857  result = theOverview->getNumberOfLines(reduced_res_level);
858  }
859  else
860  {
861  int x, y;
862  getMaxSize(reduced_res_level, x, y);
863  result = y;
864  }
865  }
866 
867  return result;
868 }
869 
870 //*******************************************************************
871 // Public Method:
872 //*******************************************************************
874 {
875  ossim_uint32 result = 0;
876  if ( isOpen() && isValidRLevel(reduced_res_level) )
877  {
878  if(theOverview.valid() && theOverview->isValidRLevel(reduced_res_level))
879  {
880  result = theOverview->getNumberOfLines(reduced_res_level);
881  }
882  else
883  {
884  int x, y;
885  getMaxSize(reduced_res_level, x, y);
886  result = x;
887  }
888  }
889  return result;
890 }
891 
892 //*******************************************************************
893 // Public Method:
894 //*******************************************************************
896 {
897  ossimIrect result;
898  result.makeNan();
899 
900  int x, y;
901  getMaxSize(reduced_res_level, x, y);
902  if(x&&y)
903  {
904  return ossimIrect(0,
905  0,
906  x - 1,
907  y - 1);
908  }
909 
910  if (result.hasNans())
911  {
912  return ossimImageHandler::getImageRectangle(reduced_res_level);
913  }
914 
915  return result;
916 }
917 
918 //*******************************************************************
919 // Public Method:
920 //*******************************************************************
922  ossimDpt& result) const
923 {
924  if (resLevel == 0)
925  {
926  result.x = 1.0;
927  result.y = 1.0;
928  }
929  else
930  {
931  /*
932  ESH 02/2009 -- No longer assume powers of 2 reduction
933  in linear size from resLevel 0 (Tickets # 467,529).
934  */
935  ossim_int32 x = getNumberOfLines(resLevel);
937 
938  if ( x > 0 && x0 > 0 )
939  {
940  result.x = ((double)x) / x0;
941  }
942  else
943  {
944  result.x = 1.0 / (1<<resLevel);
945  }
946 
947  result.y = result.x;
948  }
949 }
950 
952 {
953  return theDriver;
954 }
955 
956 //*******************************************************************
957 // Public method:
958 //*******************************************************************
960  const char* prefix) const
961 {
962  kwl.add(prefix,
963  "entry",
965  true);
967  {
968  kwl.add(prefix,
969  "entry_string",
971  true);
972  }
973 
974  bool result = ossimImageHandler::saveState(kwl, prefix);
975 
976  if (traceDebug())
977  {
979  << "DEBUG:"
980  << "\nossimGdalTileSource::saveState keywordlist:\n"
981  << kwl
982  << std::endl;
983  }
984 
985  return result;
986 }
987 
988 //*******************************************************************
989 // Public method:
990 //*******************************************************************
992  const char* prefix)
993 {
994  // Call base class first to set "theImageFile".
995  if (ossimImageHandler::loadState(kwl, prefix))
996  {
997  // Check for an entry.
998  const char* lookup = kwl.find(prefix, "entry");
999  if(lookup)
1000  {
1001  ossim_uint32 entry = ossimString(lookup).toUInt32();
1002 
1003  // setCurrentEntry calls open but does not have a return.
1004  setCurrentEntry(entry);
1005  return isOpen();
1006  }
1007  lookup = kwl.find(prefix, PRESERVE_PALETTE_KW);
1008  if ( lookup )
1009  {
1010  setPreservePaletteIndexesFlag(ossimString(lookup).toBool());
1011  }
1012 
1013  return open();
1014  }
1015 
1016  return false;
1017 }
1018 
1019 //*****************************************************************************
1024 //*****************************************************************************
1026 {
1027  if ( !theGeometry )
1028  {
1029  //---
1030  // Check factory for external geom:
1031  //---
1033 
1034  if ( !theGeometry )
1035  {
1036  //---
1037  // WARNING:
1038  // Must create/set the geometry at this point or the next call to
1039  // ossimImageGeometryRegistry::extendGeometry will put us in an infinite loop
1040  // as it does a recursive call back to ossimImageHandler::getImageGeometry().
1041  //---
1043 
1044  //---
1045  // And finally allow factories to extend the internal geometry.
1046  // This allows plugins for tagged formats with tags not know in the base
1047  // to extend the internal geometry.
1048  //
1049  // Plugins can do handler->getImageGeometry() then modify/extend.
1050  //---
1051  if( !ossimImageGeometryRegistry::instance()->extendGeometry( this ) )
1052  {
1053  // Check for internal, for geotiff, nitf and so on as last resort for getting
1054  // some kind of geometry
1055  // loaded
1057  }
1058 
1059  if ( !theGeometry )
1060  {
1062  }
1063  }
1064 
1065  // Set image things the geometry object should know about.
1067  }
1068 
1069  return theGeometry;
1070 }
1071 
1073 {
1075 
1076  ossimString fileBase = theImageFile.noExtension();
1077  ossimFilename xmlFile = ossimString(fileBase + ".xml");
1078  if (!xmlFile.exists())//try the xml file which includes the entire source file name
1079  {
1080  xmlFile = theImageFile + ".xml";
1081  }
1082  ossimFgdcXmlDoc* fgdcXmlDoc = new ossimFgdcXmlDoc;
1083  if ( fgdcXmlDoc->open(xmlFile) )
1084  {
1085  ossimRefPtr<ossimProjection> proj = fgdcXmlDoc->getProjection();
1086  if ( proj.valid() )
1087  {
1088  geom = new ossimImageGeometry;
1089  geom->setProjection( proj.get() );
1090  }
1091  }
1092  delete fgdcXmlDoc;
1093  fgdcXmlDoc = 0;
1094 
1095  return geom;
1096 }
1097 
1098 //*************************************************************************************************
1101 //*************************************************************************************************
1103 {
1104  static const char MODULE[] = "ossimGdalTileSource::getImageGeometry";
1105 
1106  if( !isOpen())
1107  {
1109  }
1110 
1111  // GDAL Driver Name
1112  ossimString driverName = theDriver ? GDALGetDriverShortName( theDriver ) : "";
1113 
1114  // Projection Reference
1115  const char* wkt = GDALGetProjectionRef( theDataset );
1116  ossim_uint32 gcpCount = GDALGetGCPCount(theDataset);
1117  if(!ossimString(wkt).empty() && gcpCount < 4)
1118  {
1119  if(traceDebug())
1120  {
1121  CLOG << "WKT PROJECTION STRING = " << wkt << std::endl;
1122  }
1123  }
1124  else
1125  {
1126  // if ESAT driver we will for now try to creae a projection for it
1127  //
1128  if (traceDebug())
1129  {
1131  << "GDALGetGCPCount = " << gcpCount << std::endl;
1132  }
1133 
1134  if(gcpCount > 3)
1135  {
1136  ossimRefPtr<ossimProjection> projGcp = 0;
1137  wkt = GDALGetGCPProjection(theDataset);
1138  if (!ossimString(wkt).empty())
1139  {
1140  ossimKeywordlist kwl;
1141 
1142  if (wktTranslator.toOssimKwl(wkt, kwl))
1143  {
1145  }
1146  }
1147 
1148  bool isGeo = true;
1149  if (projGcp.valid())
1150  {
1152  if (mapProj.valid())
1153  {
1154  if (!mapProj->isGeographic())
1155  {
1156  isGeo = false;
1157  }
1158  }
1159  }
1160  ossim_uint32 idx = 0;
1161  const GDAL_GCP* gcpList = GDALGetGCPs(theDataset);
1162  ossimTieGptSet tieSet;
1163  if(!gcpList) return ossimRefPtr<ossimImageGeometry>();
1164 
1165  for(idx = 0; idx < gcpCount; ++idx)
1166  {
1167  //---
1168  // Modified to add all tie points if gcpCount is < than
1169  // 40 as dataset with five gcp's was failing because only one
1170  // tiepoint was set from "if (idx%10 == 0)" logic.
1171  // (drb - 20080615)
1172  //---
1173  if ((gcpCount < 40) || (idx%10 == 0))
1174  {
1175  ossimDpt dpt(gcpList[idx].dfGCPPixel, gcpList[idx].dfGCPLine);
1176  ossimGpt gpt;
1177  if (isGeo == false)
1178  {
1179  ossimDpt dptEastingNorthing(gcpList[idx].dfGCPX, gcpList[idx].dfGCPY);
1180  gpt = projGcp->inverse(dptEastingNorthing);
1181  gpt.hgt = gcpList[idx].dfGCPZ;
1182  }
1183  else
1184  {
1185  gpt = ossimGpt(gcpList[idx].dfGCPY, gcpList[idx].dfGCPX, gcpList[idx].dfGCPZ);
1186  }
1187 
1188  tieSet.addTiePoint(new ossimTieGpt(gpt, dpt, .5));
1189 
1190  if (traceDebug())
1191  {
1193  << "Added tie point for gcp[" << idx << "]: "
1194  << dpt << ", " << gpt << std::endl;
1195  }
1196  }
1197  }
1198 
1200  bilinProj->optimizeFit(tieSet);
1201 
1202  // Set the projection and return this handler's image geometry:
1204  geom->setProjection(bilinProj.get());
1205  return geom;
1206  }
1207  }
1208 
1209  // Geometric Transform
1210  double geoTransform[6];
1211  bool transOk = GDALGetGeoTransform( theDataset, geoTransform ) == CE_None;
1212  if (!transOk)
1213  {
1214  if (traceDebug())
1215  {
1217  << MODULE << "DEBUG: GDALGetGeoTransform failed..." << std::endl;
1218  }
1220  }
1221  if(traceDebug())
1222  {
1223  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: Geo transform = <"
1224  << geoTransform[0] << ", " << geoTransform[1] << ", " << geoTransform[2] << ", "
1225  << geoTransform[3] << ", " << geoTransform[2] << ", " << geoTransform[5] << ">"
1226  << std::endl;
1227  }
1228 
1229  // Convert WKT string to OSSIM keywordlist
1230  ossimKeywordlist kwl;
1231  if ( !wktTranslator.toOssimKwl(wkt, kwl) )
1232  {
1233  // sometimes geographic is just encoded in the matrix transform. We can do a crude test
1234  // to see if the tie points
1235  // are within geographic bounds and then assume geographic so we can still load
1236  // projections
1237  //
1238  if(transOk&&(driverName=="AAIGrid"))
1239  {
1240  if(traceDebug())
1241  {
1242  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG:TESTING GEOGRAPHIC = <"
1243  << geoTransform[0] << ", " << geoTransform[1] << ", " << geoTransform[2] << ", "
1244  << geoTransform[3] << ", " << geoTransform[2] << ", " << geoTransform[5] << ">"
1245  << std::endl;
1246  }
1247  if((std::fabs(geoTransform[0]) < (180.0+FLT_EPSILON))&&
1248  (std::fabs(geoTransform[3]) < (90.0 + FLT_EPSILON)))
1249  {
1250  ossimTieGptSet tieSet;
1251  ossimIrect rect = getBoundingRect();
1252  if(rect.hasNans()) return ossimRefPtr<ossimImageGeometry>();
1253  // we will do an affine transform for the projeciton information
1254  //
1255  ossimDpt ul = rect.ul();
1256  tieSet.addTiePoint(new ossimTieGpt(ossimGpt(geoTransform[3] + ul.x*geoTransform[4] + ul.y*geoTransform[5],
1257  geoTransform[0] + ul.x*geoTransform[1] + ul.y*geoTransform[2]),
1258  ul, .5));
1259  ossimDpt ur = rect.ur();
1260  tieSet.addTiePoint(new ossimTieGpt(ossimGpt(geoTransform[3] + ur.x*geoTransform[4] + ur.y*geoTransform[5],
1261  geoTransform[0] + ur.x*geoTransform[1] + ur.y*geoTransform[2]),
1262  ur, .5));
1263  ossimDpt lr = rect.lr();
1264  tieSet.addTiePoint(new ossimTieGpt(ossimGpt(geoTransform[3] + lr.x*geoTransform[4] + lr.y*geoTransform[5],
1265  geoTransform[0] + lr.x*geoTransform[1] + lr.y*geoTransform[2]),
1266  lr, .5));
1267  ossimDpt ll = rect.ll();
1268  tieSet.addTiePoint(new ossimTieGpt(ossimGpt(geoTransform[3] + ll.x*geoTransform[4] + ll.y*geoTransform[5],
1269  geoTransform[0] + ll.x*geoTransform[1] + ll.y*geoTransform[2]),
1270  ll, .5));
1272  bilinProj->optimizeFit(tieSet);
1273 
1274  // Set the projection and return this handler's image geometry:
1276  geom->setProjection(bilinProj.get());
1277  return geom;
1278  }
1279  else
1280  {
1282  }
1283  }
1284  else
1285  {
1286  if (traceDebug())
1287  {
1289  << MODULE << "DEBUG: wktTranslator.toOssimKwl failed..." << std::endl;
1290  }
1292  }
1293  }
1294 
1295  // GARRETT! Where is this coming from?
1296  // Projection, Datum, and Units
1297  const char* prefix = 0; // legacy code. KWL is used internally now so don't need prefix
1298  ossimString proj_type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
1299  ossimString datum_type = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
1300  ossimString units = kwl.find(prefix, ossimKeywordNames::UNITS_KW);
1301 
1302  ossimDpt gsd(fabs(geoTransform[1]), fabs(geoTransform[5]));
1303 
1304  ossimUnitType savedUnitType = static_cast<ossimUnitType>(ossimUnitTypeLut::instance()->getEntryNumber(units));
1305  ossimUnitType unitType = savedUnitType;
1306  if(unitType == OSSIM_UNIT_UNKNOWN)
1307  {
1308  unitType = OSSIM_METERS;
1309  units = "meters";
1310  }
1311 
1312  // AIG driver considered pixel is area:
1313  if(driverName == "AIG")
1315 
1316  ossimDpt tie(geoTransform[0], geoTransform[3]);
1317 
1319  {
1320  tie.x += gsd.x/2.0;
1321  tie.y -= gsd.y/2.0;
1322  }
1323 
1324  geoTransform[0] = tie.x;
1325  geoTransform[3] = tie.y;
1326 
1327  if(proj_type == "ossimLlxyProjection" ||
1328  proj_type == "ossimEquDistCylProjection")
1329  {
1330  if(savedUnitType == OSSIM_UNIT_UNKNOWN)
1331  {
1332  unitType = OSSIM_DEGREES;
1333  units = "degrees";
1334  }
1335  }
1336  kwl.add(prefix, ossimKeywordNames::PIXEL_SCALE_XY_KW, gsd.toString(), true);
1337  kwl.add(prefix, ossimKeywordNames::PIXEL_SCALE_UNITS_KW, units, true);
1338  kwl.add(prefix, ossimKeywordNames::TIE_POINT_XY_KW, tie.toString(), true);
1339  kwl.add(prefix, ossimKeywordNames::TIE_POINT_UNITS_KW, units, true);
1340  kwl.add(prefix, ossimKeywordNames::TIE_POINT_UNITS_KW, units, true);
1341  std::stringstream mString;
1342  mString << ossimString::toString(geoTransform[1], 20) << " " << ossimString::toString(geoTransform[2], 20)
1343  << " " << 0 << " " << ossimString::toString(geoTransform[0], 20)
1344  << " " << ossimString::toString(geoTransform[4], 20) << " " << ossimString::toString(geoTransform[5], 20)
1345  << " " << 0 << " " << ossimString::toString(geoTransform[3], 20)
1346  << " " << 0 << " " << 0 << " " << 1 << " " << 0
1347  << " " << 0 << " " << 0 << " " << 0 << " " << 1;
1348 
1349  kwl.add(prefix, ossimKeywordNames::IMAGE_MODEL_TRANSFORM_MATRIX_KW, mString.str().c_str(), true);
1350  kwl.add(prefix, ossimKeywordNames::IMAGE_MODEL_TRANSFORM_UNIT_KW, units, true);
1351 
1352  //---
1353  // SPECIAL CASE: ArcGrid in British National Grid
1354  //---
1355  if(driverName == "AIG" && datum_type.contains("OGB"))
1356  {
1357  ossimFilename prj_file = theImageFile.path() + "/prj.adf";
1358 
1359  if(prj_file.exists())
1360  {
1361  ossimKeywordlist prj_kwl(' ');
1362  prj_kwl.addFile(prj_file);
1363 
1364  ossimString proj = prj_kwl.find("Projection");
1365 
1366  // Reset projection and Datum correctly for BNG.
1367  if(proj.upcase().contains("GREATBRITAIN"))
1368  {
1369 
1370  kwl.add(prefix, ossimKeywordNames::TYPE_KW,
1371  "ossimBngProjection", true);
1372 
1373  ossimString datum = prj_kwl.find("Datum");
1374 
1375  if(datum != "")
1376  {
1377  if(datum == "OGB_A")
1378  datum = "OGB-A";
1379  else if(datum == "OGB_B")
1380  datum = "OGB-B";
1381  else if(datum == "OGB_C")
1382  datum = "OGB-C";
1383  else if(datum == "OGB_D")
1384  datum = "OGB-D";
1385  else if(datum == "OGB_M")
1386  datum = "OGB-M";
1387  else if(datum == "OGB_7")
1388  datum = "OGB-7";
1389 
1390  kwl.add(prefix, ossimKeywordNames::DATUM_KW,
1391  datum, true);
1392  }
1393  }
1394  }
1395  else
1396  {
1397  if (traceDebug())
1398  {
1400  << "MODULE DEBUG:"
1401  << "\nUnable to accurately support ArcGrid due to missing"
1402  << " prj.adf file." << std::endl;
1403  }
1405  }
1406 
1407  } // End of "if(driverName == "AIG" && datum_type == "OSGB_1936")"
1408  if (traceDebug())
1409  {
1411  << MODULE << " DEBUG:"
1412  << "\nwktTranslator keyword list:\n"
1413  << kwl
1414  << std::endl;
1415  }
1416 
1417  // Save for next time...
1420  geom->setProjection(proj); // assumes ownership via ossiRefPtr mechanism
1421 
1422  return geom;
1423 }
1424 
1425 //*******************************************************************
1426 // Public method:
1427 //*******************************************************************
1429 {
1430  return ( theTile.valid() ? theTile->getWidth() : 0 );
1431 }
1432 
1433 //*******************************************************************
1434 // Public method:
1435 //*******************************************************************
1437 {
1438  return ( theTile.valid() ? theTile->getHeight() : 0 );
1439 }
1440 
1442 {
1444 
1445  //---
1446  // If theLut is valid typical output is eight bit RGB unless the flag is set to preserve
1447  // palette indexes in which case it is typically 16 bit.
1448  //---
1450  {
1451  // Input different than output.
1452  result = OSSIM_UINT8;
1453  }
1454 
1455  if (traceDebug())
1456  {
1458  << "ossimGdalTileSource::getOutputScalarType debug:"
1459  << "\nOutput scalar: " << result << std::endl;
1460  }
1461 
1462  return result;
1463 }
1464 
1466 {
1468 
1469 
1470  switch(theGdtType)
1471  {
1472  case GDT_Byte:
1473  {
1474  result = OSSIM_UINT8;
1475  break;
1476  }
1477  case GDT_UInt16:
1478  {
1479  result = OSSIM_USHORT16;
1480  break;
1481  }
1482  case GDT_Int16:
1483  {
1484  result = OSSIM_SSHORT16;
1485  break;
1486  }
1487  case GDT_UInt32:
1488  {
1489  result = OSSIM_UINT32;
1490  break;
1491 
1492  }
1493  case GDT_Int32:
1494  {
1495  ossim_int32 sizeType = GDALGetDataTypeSize(theGdtType)/8;
1496  if(sizeType == 2)
1497  {
1498  result = OSSIM_SSHORT16;
1499  theGdtType = GDT_Int16;
1500  }
1501  else
1502  {
1503  result = OSSIM_SINT32;
1504  theGdtType = GDT_Int32;
1505  }
1506  break;
1507  }
1508  case GDT_Float32:
1509  {
1510  result = OSSIM_FLOAT;
1511  break;
1512  }
1513  case GDT_Float64:
1514  {
1515  result = OSSIM_DOUBLE;
1516  break;
1517  }
1518  case GDT_CInt16:
1519  {
1520  result = OSSIM_SINT16;
1521  break;
1522  }
1523  case GDT_CInt32:
1524  {
1525  result = OSSIM_SINT32;
1526  break;
1527  }
1528  case GDT_CFloat32:
1529  {
1530  result = OSSIM_FLOAT32;
1531  break;
1532  }
1533  case GDT_CFloat64:
1534  {
1535  result = OSSIM_FLOAT64;
1536  break;
1537  }
1538  default:
1539  break;
1540  }
1541 
1542  if (traceDebug())
1543  {
1545  << "ossimGdalTileSource::getInputScalarType debug:"
1546  << "\nGDAL Type: " << theGdtType
1547  << "\nInput scalar: " << result << std::endl;
1548  }
1549 
1550  return result;
1551 }
1552 
1554 {
1555  double result = ossim::defaultNull(getOutputScalarType());
1556 
1557  if ( theLut.valid() )
1558  {
1559  //---
1560  // If serving up lut data zero may not be null.
1561  // If m_preservePaletteIndexesFlag is set use the first alpha set to zero in the lut.
1562  //---
1564  if ( np != -1 ) // -1 means the lut does not know a null value.
1565  {
1566  result = theLut->getNullPixelIndex();
1567  }
1568  }
1569  else if(theMetaData.getNumberOfBands())
1570  {
1571  result = ossimImageHandler::getNullPixelValue(band);
1572  }
1573  else if (theNullPixValues && (band < getNumberOfOutputBands()) )
1574  {
1575  result = theNullPixValues[band];
1576  }
1577  return result;
1578 }
1579 
1581 {
1582  double result = ossim::defaultMin(getOutputScalarType());
1583  if ( theLut.valid() )
1584  {
1585  result = 0;
1586  }
1587  else if(theMetaData.getNumberOfBands())
1588  {
1589  result = ossimImageHandler::getMinPixelValue(band);
1590  }
1591  else if (theMinPixValues && (band < getNumberOfOutputBands()) )
1592  {
1593  result = theMinPixValues[band];
1594  }
1595  return result;
1596 }
1597 
1599 {
1600  double result = ossim::defaultMax(getOutputScalarType());
1602  {
1603  result = theLut->getNumberOfEntries() - 1;
1604  }
1605  else if(theMetaData.getNumberOfBands())
1606  {
1607  result = ossimImageHandler::getMaxPixelValue(band);
1608  }
1609  else if ( theMaxPixValues && (band < getNumberOfOutputBands()) )
1610  {
1611  result = theMaxPixValues[band];
1612  }
1613  return result;
1614 }
1615 
1617 {
1618  ossim_uint32 bands = GDALGetRasterCount(theDataset);
1619 
1620  if(theMinPixValues)
1621  {
1622  delete [] theMinPixValues;
1623  theMinPixValues = 0;
1624  }
1625  if(theMaxPixValues)
1626  {
1627  delete [] theMaxPixValues;
1628  theMaxPixValues = 0;
1629  }
1630  if(theNullPixValues)
1631  {
1632  delete [] theNullPixValues;
1633  theNullPixValues = 0;
1634  }
1635  if(isIndexTo3Band())
1636  {
1637  int i = 0;
1638  theMinPixValues = new double[3];
1639  theMaxPixValues = new double[3];
1640  theNullPixValues = new double[3];
1641 
1642  for(i = 0; i < 3; ++i)
1643  {
1644  theMinPixValues[i] = 1;
1645  theMaxPixValues[i] = 255;
1646  theNullPixValues[i] = 0;
1647  }
1648  }
1649  else if(isIndexTo1Band())
1650  {
1651  theMinPixValues = new double[1];
1652  theMaxPixValues = new double[1];
1653  theNullPixValues = new double[1];
1654 
1655  *theNullPixValues = 0;
1656  *theMaxPixValues = 255;
1657  *theMinPixValues = 1;
1658  }
1659  else
1660  {
1661  if(!theMinPixValues && !theMaxPixValues&&bands)
1662  {
1663  theMinPixValues = new double[bands];
1664  theMaxPixValues = new double[bands];
1665  theNullPixValues = new double[bands];
1666  }
1667  for(ossim_int32 band = 0; band < (ossim_int32)bands; ++band)
1668  {
1669  GDALRasterBandH aBand=0;
1670 
1671  aBand = GDALGetRasterBand(theDataset, band+1);
1672 
1673  int minOk=1;
1674  int maxOk=1;
1675  int nullOk=1;
1676 
1677  if(aBand)
1678  {
1679  if(hasMetaData())
1680  {
1681  theMinPixValues[band] = theMetaData.getMinPix(band);
1682  theMaxPixValues[band] = theMetaData.getMaxPix(band);
1683  theNullPixValues[band] = theMetaData.getNullPix(band);
1684  }
1685  else
1686  {
1687  ossimString driverName = theDriver ? GDALGetDriverShortName( theDriver ) : "";
1688 
1689  // ESH 12/2008 -- Allow OSSIM to rescale the image data
1690  // to the min/max values found in the raster data only
1691  // if it was not acquired with the following drivers:
1692  if ( driverName.contains("JP2KAK") ||
1693  driverName.contains("JPEG2000") ||
1694  driverName.contains("NITF") )
1695  {
1699  }
1700  else
1701  {
1702  theMinPixValues[band] = GDALGetRasterMinimum(aBand, &minOk);
1703  theMaxPixValues[band] = GDALGetRasterMaximum(aBand, &maxOk);
1704  theNullPixValues[band] = GDALGetRasterNoDataValue(aBand, &nullOk);
1705  }
1706 
1707  if(!nullOk)
1708  {
1710  }
1711  }
1712 
1713  if(!minOk||!maxOk)
1714  {
1717  }
1718  }
1719  else
1720  {
1723  }
1724 
1725  // Sanity check for bad null:
1727  {
1729  }
1730  }
1731  }
1732 }
1733 
1735 {
1736  ossim_uint32 result = 1;
1737  //---
1738  // Note: This code was shut off since we currently don't utilize gdal overviews. Returning
1739  // this causes the overview builder will incorrectly start at the wrong res level.
1740  // drb - 20110503
1741  //---
1742  if(theDataset&&!theOverview)
1743  {
1744  if(GDALGetRasterCount(theDataset))
1745  {
1746  GDALRasterBandH band = GDALGetRasterBand(theDataset, 1);
1747  if(GDALGetOverviewCount(band))
1748  {
1749  result += (GDALGetOverviewCount(band));
1750  }
1751  }
1752  }
1753  if (theOverview.valid())
1754  {
1756  }
1757  return result;
1758 }
1759 
1761  ossim_uint32 aGdalBandStart,
1762  ossim_uint32 anOssimBandStart)
1763 {
1764  // Typical case 16 bit indexes, eight bit out, NOT 16 bit out.
1765  ossimScalarType inScalar = getInputScalarType();
1766  ossimScalarType outScalar = getOutputScalarType();
1767 
1768  if ( ( inScalar == OSSIM_UINT8 ) && ( outScalar == OSSIM_UINT8 ) )
1769  {
1770  loadIndexTo3BandTileTemplate(ossim_uint8(0), // input type
1771  ossim_uint8(0), // output type
1772  clipRect,
1773  aGdalBandStart,
1774  anOssimBandStart);
1775  }
1776  else if ( ( inScalar == OSSIM_UINT16 ) && ( outScalar == OSSIM_UINT8 ) )
1777  {
1778  loadIndexTo3BandTileTemplate(ossim_uint16(0), // input type
1779  ossim_uint8(0), // output type
1780  clipRect,
1781  aGdalBandStart,
1782  anOssimBandStart);
1783  }
1784 
1785  else if ( ( inScalar == OSSIM_UINT16 ) && ( outScalar == OSSIM_UINT16 ) )
1786  {
1787  loadIndexTo3BandTileTemplate(ossim_uint16(0), // input type
1788  ossim_uint16(0), // output type
1789  clipRect,
1790  aGdalBandStart,
1791  anOssimBandStart);
1792  }
1793  else if ( ( inScalar == OSSIM_SINT16 ) && ( outScalar == OSSIM_SINT16 ) )
1794  {
1795  loadIndexTo3BandTileTemplate(ossim_sint16(0), // input type
1796  ossim_sint16(0), // output type
1797  clipRect,
1798  aGdalBandStart,
1799  anOssimBandStart);
1800  }
1801  else if ( ( inScalar == OSSIM_FLOAT32 ) && ( outScalar == OSSIM_FLOAT32 ) )
1802  {
1803  loadIndexTo3BandTileTemplate(ossim_float32(0.0), // input type
1804  ossim_float32(0.0), // output type
1805  clipRect,
1806  aGdalBandStart,
1807  anOssimBandStart);
1808  }
1809  else if ( ( inScalar == OSSIM_FLOAT64 ) && ( outScalar == OSSIM_FLOAT64 ) )
1810  {
1811  loadIndexTo3BandTileTemplate(ossim_float64(0.0), // input type
1812  ossim_float64(0.0), // output type
1813  clipRect,
1814  aGdalBandStart,
1815  anOssimBandStart);
1816  }
1817  else if ( ( inScalar == OSSIM_FLOAT64 ) && ( outScalar == OSSIM_UINT8 ) )
1818  {
1819  loadIndexTo3BandTileTemplate(ossim_float64(0.0), // input type
1820  ossim_uint8(0.0), // output type
1821  clipRect,
1822  aGdalBandStart,
1823  anOssimBandStart);
1824  }
1825  else
1826  {
1828  << __FILE__ << __LINE__
1829  << " ossimGdalTileSource::loadIndexTo3BandTile WARNING!\n"
1830  << "Unsupported scalar types:\nInupt scalar: " << inScalar
1831  << "\nOutput scalar: " << outScalar
1832  << std::endl;
1833  }
1834 }
1835 
1836 template<class InputType, class OutputType>
1838  OutputType /* out */,
1839  const ossimIrect& clipRect,
1840  ossim_uint32 aGdalBandStart,
1841  ossim_uint32 anOssimBandStart)
1842 {
1843  const InputType* s = reinterpret_cast<const InputType*>(theSingleBandTile->getBuf());
1844  GDALRasterBandH aBand=0;
1845  aBand = GDALGetRasterBand(theDataset, aGdalBandStart);
1846  GDALColorTableH table = GDALGetRasterColorTable(aBand);
1847 
1848  // ossim_uint32 rasterCount = GDALGetRasterCount(theDataset);
1849  ossim_uint32 anOssimBandEnd = anOssimBandStart + 2;
1850  if(getNumberOfOutputBands() < anOssimBandEnd)
1851  {
1852  return;
1853  }
1854  // Get the width of the buffers.
1856  ossim_uint32 d_width = theTile->getWidth();
1858  ossimIrect img_rect = theTile->getImageRectangle();
1859 
1860  // Move the pointers to the first valid pixel.
1861  s += (clipRect.ul().y - src_rect.ul().y) * s_width +
1862  clipRect.ul().x - src_rect.ul().x;
1863  ossim_uint32 clipHeight = clipRect.height();
1864  ossim_uint32 clipWidth = clipRect.width();
1865 
1866  OutputType* d[3];
1867  d[0]= static_cast<OutputType*>(theTile->getBuf(anOssimBandStart));
1868  d[1]= static_cast<OutputType*>(theTile->getBuf(anOssimBandStart + 1));
1869  d[2]= static_cast<OutputType*>(theTile->getBuf(anOssimBandStart + 2));
1870 
1871 #if 0 /* Code shut off to treat all indexes as valid. */
1872  OutputType np[3];
1873  np[0] = (OutputType)theTile->getNullPix(0);
1874  np[1] = (OutputType)theTile->getNullPix(1);
1875  np[2] = (OutputType)theTile->getNullPix(2);
1876 
1877  OutputType minp[3];
1878  minp[0] = (OutputType)theTile->getMinPix(0);
1879  minp[1] = (OutputType)theTile->getMinPix(1);
1880  minp[2] = (OutputType)theTile->getMinPix(2);
1881 #endif
1882 
1883  ossim_uint32 offset = (clipRect.ul().y - img_rect.ul().y) * d_width +
1884  clipRect.ul().x - img_rect.ul().x;
1885  d[0] += offset;
1886  d[1] += offset;
1887  d[2] += offset;
1888 
1889  // Copy the data.
1890 
1891  GDALPaletteInterp interp = GDALGetPaletteInterpretation(table);
1892 
1893  for (ossim_uint32 line = 0; line < clipHeight; ++line)
1894  {
1895  for (ossim_uint32 sample = 0; sample < clipWidth; ++sample)
1896  {
1897  GDALColorEntry entry;
1898  if(GDALGetColorEntryAsRGB(table, s[sample], &entry))
1899  {
1900  if(interp == GPI_RGB)
1901  {
1902  if(!entry.c4)
1903  {
1904  d[0][sample] = 0;
1905  d[1][sample] = 0;
1906  d[2][sample] = 0;
1907  }
1908  else
1909  {
1910 #if 0 /* Code shut off to treat all indexes as valid. */
1911  d[0][sample] = entry.c1==np[0]?minp[0]:entry.c1;
1912  d[1][sample] = entry.c2==np[1]?minp[1]:entry.c2;
1913  d[2][sample] = entry.c3==np[2]?minp[2]:entry.c3;
1914 #endif
1915  d[0][sample] = entry.c1;
1916  d[1][sample] = entry.c2;
1917  d[2][sample] = entry.c3;
1918 
1919  }
1920  }
1921  else
1922  {
1923  d[0][sample] = entry.c1;
1924  d[1][sample] = entry.c2;
1925  d[2][sample] = entry.c3;
1926  }
1927  }
1928  else
1929  {
1930  d[0][sample] = 0;
1931  d[1][sample] = 0;
1932  d[2][sample] = 0;
1933  }
1934  }
1935 
1936  s += s_width;
1937  d[0] += d_width;
1938  d[1] += d_width;
1939  d[2] += d_width;
1940  }
1941 
1942 }
1943 
1944 bool ossimGdalTileSource::isIndexTo3Band(int bandNumber)const
1945 {
1946  GDALRasterBandH band = GDALGetRasterBand(theDataset, bandNumber);
1947  if(GDALGetRasterColorInterpretation(band)==GCI_PaletteIndex)
1948  {
1949  GDALColorTableH table = GDALGetRasterColorTable(band);
1950  GDALPaletteInterp interp = GDALGetPaletteInterpretation(table);
1951  if( (interp == GPI_RGB) ||
1952  (interp == GPI_HLS)||
1953  (interp == GPI_CMYK))
1954  {
1955  return true;
1956  }
1957  }
1958 
1959  return false;
1960 }
1961 
1962 bool ossimGdalTileSource::isIndexTo1Band(int bandNumber)const
1963 {
1964  GDALRasterBandH band = GDALGetRasterBand(theDataset, bandNumber);
1965  if(GDALGetRasterColorInterpretation(band)==GCI_PaletteIndex)
1966  {
1967  GDALColorTableH table = GDALGetRasterColorTable(band);
1968  GDALPaletteInterp interp = GDALGetPaletteInterpretation(table);
1969  if(interp == GPI_Gray)
1970  {
1971  return true;
1972  }
1973  }
1974 
1975  return false;
1976 }
1977 
1979 {
1980  if(isIndexed(bandNumber))
1981  {
1982  GDALRasterBandH band = GDALGetRasterBand(theDataset, bandNumber);
1983  if(GDALGetRasterColorInterpretation(band)==GCI_PaletteIndex)
1984  {
1985  GDALColorTableH table = GDALGetRasterColorTable(band);
1986  GDALPaletteInterp interp = GDALGetPaletteInterpretation(table);
1987  switch(interp)
1988  {
1989  case GPI_CMYK:
1990  case GPI_RGB:
1991  case GPI_HLS:
1992  {
1993  return 3;
1994  }
1995  case GPI_Gray:
1996  {
1997  return 1;
1998  }
1999  }
2000  }
2001  }
2002 
2003  return 0;
2004 }
2005 
2006 bool ossimGdalTileSource::isIndexed(int aGdalBandNumber)const
2007 {
2008  if(aGdalBandNumber <= GDALGetRasterCount(theDataset))
2009  {
2010  GDALRasterBandH band = GDALGetRasterBand(theDataset, aGdalBandNumber);
2011  if(!band) return false;
2012  if(GDALGetRasterColorInterpretation(band)==GCI_PaletteIndex)
2013  {
2014  return true;
2015  }
2016  }
2017 
2018  return false;
2019 }
2020 
2021 // Temp "return 128x128;" until I can figure out how to tell if tiled (gcp)
2023 {
2024  return 128;
2025 }
2026 
2028 {
2029  return 128;
2030 }
2031 
2033  int& maxX,
2034  int& maxY)const
2035 {
2036  int aGdalBandIndex = 0;
2037  maxX = 0;
2038  maxY = 0;
2039 
2040  if(theOverview.valid() && theOverview->isValidRLevel(resLevel))
2041  {
2042  ossimIrect rect = theOverview->getBoundingRect(resLevel);
2043  if(!rect.hasNans())
2044  {
2045  maxX = rect.width();
2046  maxY = rect.height();
2047  }
2048  return;
2049  }
2050 
2051  for(aGdalBandIndex=1;
2052  (int)aGdalBandIndex <= (int)GDALGetRasterCount(theDataset);
2053  ++aGdalBandIndex)
2054  {
2055  GDALRasterBandH aBand = resolveRasterBand(resLevel, aGdalBandIndex);
2056  if(aBand)
2057  {
2058  maxY = ossim::max<int>((int)GDALGetRasterBandYSize(aBand), maxY);
2059  maxX = ossim::max<int>((int)GDALGetRasterBandXSize(aBand), maxX);
2060  }
2061  else
2062  {
2063  break;
2064  }
2065  }
2066 }
2067 
2069  int aGdalBandIndex ) const
2070 {
2071  GDALRasterBandH aBand = GDALGetRasterBand( theDataset, aGdalBandIndex );
2072 
2073  if( resLevel > 0 )
2074  {
2075  int overviewIndex = resLevel-1;
2076 
2077  GDALRasterBandH overviewBand = GDALGetOverview( aBand, overviewIndex );
2078  if ( overviewBand )
2079  {
2080  aBand = overviewBand;
2081  }
2082  }
2083 
2084  return aBand;
2085 }
2086 
2088 {
2089  ossimString result = "gdal";
2090  if ( theDriver )
2091  {
2092  const char* driver = GDALGetDriverShortName(theDriver);
2093  if ( driver )
2094  {
2095  result += "_";
2096  result += driver;
2097  }
2098  }
2099  return result;
2100 }
2101 
2103 {
2104  return ossimString("gdal reader");
2105 }
2106 
2108 {
2109  return ossimString("ossimGdalTileSource");
2110 }
2111 
2113 {
2114  return (theDataset != 0);
2115 }
2116 
2118 {
2119  return theEntryNumberToRender;
2120 }
2121 
2123 {
2124  if ( isOpen() && (theEntryNumberToRender == entryIdx) )
2125  {
2126  return true; // Nothing to do...
2127  }
2128  theDecimationFactors.clear();
2129  theGeometry = 0;
2130  theOverview = 0;
2132  m_outputBandList.clear();
2133  theEntryNumberToRender = entryIdx;
2134  return open();
2135 }
2136 
2137 void ossimGdalTileSource::getEntryList(std::vector<ossim_uint32>& entryList) const
2138 {
2139  entryList.clear();
2140  if (theSubDatasets.size())
2141  {
2142  for (ossim_uint32 i = 0; i < theSubDatasets.size(); ++i)
2143  {
2144  entryList.push_back(i);
2145  }
2146  }
2147  else
2148  {
2149  entryList.push_back(0);
2150  }
2151 }
2152 
2153 void ossimGdalTileSource:: getEntryNames(std::vector<ossimString>& entryStringList) const
2154 {
2155  if (theSubDatasets.size())
2156  {
2157  entryStringList = theSubDatasets;
2158  }
2159  else
2160  {
2161  ossimImageHandler::getEntryNames(entryStringList);
2162  }
2163 }
2164 
2166 {
2167  //---
2168  // Skip up to and including '=' and filter out the quotes '"'.
2169  //---
2170  ossimString s;
2171  bool atStart = false;
2172  for (ossim_uint32 pos = 0; pos < subString.size(); ++pos)
2173  {
2174  if ( *(subString.begin()+pos) == '=')
2175  {
2176  atStart = true; // Start recording after this.
2177  continue; // Skip the '='.
2178  }
2179  if (atStart)
2180  {
2181  //if (*(subString.begin()+pos) == '\"')
2182  //{
2183  // continue; // Skip the '='.
2184  //}
2185  s.push_back(*(subString.begin()+pos)); // Record the character.
2186  }
2187  }
2188  return s;
2189 }
2190 
2191 bool ossimGdalTileSource::isBlocked( int /* band */ )const
2192 {
2193  return m_isBlocked;
2194 }
2195 
2197 {
2198  theLut = 0; // ossimRefPtr not a leak.
2199 
2200  if(isIndexed(1)&&theDataset)
2201  {
2202  GDALColorTableH aTable = GDALGetRasterColorTable(GDALGetRasterBand( theDataset, 1 ));
2203  GDALPaletteInterp interp = GDALGetPaletteInterpretation(aTable);
2204  if(aTable && ( (interp == GPI_Gray) || (interp == GPI_RGB)))
2205  {
2206  GDALColorEntry colorEntry;
2207  ossim_uint32 numberOfElements = GDALGetColorEntryCount(aTable);
2208  ossim_uint32 idx = 0;
2209  if(numberOfElements)
2210  {
2211  // GPI_Gray Grayscale (in GDALColorEntry.c1)
2212  // GPI_RGB Red, Green, Blue and Alpha in (in c1, c2, c3 and c4)
2213  theLut = new ossimNBandLutDataObject(numberOfElements,
2214  4,
2215  OSSIM_UINT8,
2216  -1);
2217 
2218  bool nullSet = false;
2219  for(idx = 0; idx < numberOfElements; ++idx)
2220  {
2221  switch(interp)
2222  {
2223  case GPI_RGB:
2224  {
2225  if(GDALGetColorEntryAsRGB(aTable, idx, &colorEntry))
2226  {
2227  (*theLut)[idx][0] = colorEntry.c1;
2228  (*theLut)[idx][1] = colorEntry.c2;
2229  (*theLut)[idx][2] = colorEntry.c3;
2230  (*theLut)[idx][3] = colorEntry.c4;
2231 
2232  if ( !nullSet )
2233  {
2235  {
2236  // If preserving palette set the null to the fix alpha of 0.
2237  if ( (*theLut)[idx][3] == 0 )
2238  {
2239  theLut->setNullPixelIndex(idx);
2240  nullSet = true;
2241  }
2242  }
2243  else
2244  {
2245  //---
2246  // Not using alpha.
2247  // Since the alpha is currently not used, look for the null
2248  // pixel index and set if we find. If at some point the alpha
2249  // is taken out this can be removed.
2250  //---
2251  if ( ( (*theLut)[idx][0] == 0 ) &&
2252  ( (*theLut)[idx][1] == 0 ) &&
2253  ( (*theLut)[idx][2] == 0 ) )
2254  {
2255  theLut->setNullPixelIndex(idx);
2256  nullSet = true;
2257  }
2258  }
2259  }
2260  }
2261  else
2262  {
2263  (*theLut)[idx][0] = 0;
2264  (*theLut)[idx][1] = 0;
2265  (*theLut)[idx][2] = 0;
2266  (*theLut)[idx][3] = 0;
2267 
2268  // Look for the null pixel index and set if we find.
2269  if ( !nullSet )
2270  {
2271  if ( (*theLut)[idx][0] == 0 )
2272  {
2273  theLut->setNullPixelIndex(idx);
2274  }
2275  }
2276  }
2277  break;
2278  }
2279  case GPI_Gray:
2280  {
2281  const GDALColorEntry* constEntry = GDALGetColorEntry(aTable, idx);
2282  if(constEntry)
2283  {
2284  (*theLut)[idx][0] = constEntry->c1;
2285  }
2286  else
2287  {
2288  (*theLut)[idx][0] = 0;
2289  }
2290  break;
2291  }
2292  default:
2293  {
2294  break;
2295  }
2296  }
2297  }
2298  }
2299  }
2300 
2301  ossim_uint32 rasterCount = GDALGetRasterCount(theDataset);
2302  for(ossim_uint32 aGdalBandIndex=1; aGdalBandIndex <= rasterCount; ++aGdalBandIndex)
2303  {
2304  GDALRasterBandH aBand = GDALGetRasterBand( theDataset, aGdalBandIndex );
2305  if (aBand)
2306  {
2307  GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT(aBand);
2308  int colCount = GDALRATGetColumnCount(hRAT);
2309  for (ossim_int32 col = 0; col < colCount; col++)
2310  {
2311  const char* colName = GDALRATGetNameOfCol(hRAT, col);
2312  if (colName)
2313  {
2314  if (strcmp(colName, "Class_Names") == 0)
2315  {
2316  std::vector<ossimString> entryLabels;
2317  ossim_int32 rowCount = GDALRATGetRowCount(hRAT);
2318  for (ossim_int32 row = 0; row < rowCount; row++)
2319  {
2320  const char* className = GDALRATGetValueAsString(hRAT, row, col);
2321  ossimString entryLabel(className);
2322  entryLabels.push_back(entryLabel);
2323  }
2324  theLut->setEntryLables(aGdalBandIndex-1, entryLabels);
2325  }
2326  }
2327  }
2328  }
2329  }
2330  }
2331 }
2332 
2334 {
2335  if ( property->getName() == PRESERVE_PALETTE_KW )
2336  {
2337  ossimString s;
2338  property->valueToString(s);
2339 
2340  // Go through set method as it will adjust theTile bands if need be.
2342  }
2343  else
2344  {
2346  }
2347 }
2348 
2350 {
2351  ossimRefPtr<ossimProperty> result = 0;
2352 
2353  if( (name == DRIVER_SHORT_NAME_KW) && isOpen() )
2354  {
2355  ossimString driverName = GDALGetDriverShortName( theDriver );
2356  result = new ossimStringProperty(name, driverName);
2357  }
2358  else if ( (name == "imag") && isOpen() )
2359  {
2360  if (theDataset)
2361  {
2362  ossimString nitfImagTag( GDALGetMetadataItem( theDataset, "NITF_IMAG", "" ) );
2363  if (!nitfImagTag.empty())
2364  {
2365  result = new ossimStringProperty(name, nitfImagTag);
2366  }
2367  }
2368  }
2369  else if ( name == PRESERVE_PALETTE_KW )
2370  {
2372  }
2373  else
2374  {
2375  result = ossimImageHandler::getProperty(name);
2376  }
2377  return result;
2378 }
2379 
2380 void ossimGdalTileSource::getPropertyNames(std::vector<ossimString>& propertyNames)const
2381 {
2382  propertyNames.push_back(DRIVER_SHORT_NAME_KW);
2383  propertyNames.push_back(PRESERVE_PALETTE_KW);
2384  ossimImageHandler::getPropertyNames(propertyNames);
2385 }
2386 
2387 bool ossimGdalTileSource::setOutputBandList(const vector<ossim_uint32>& outputBandList)
2388 {
2389  m_outputBandList.clear();
2390  if (outputBandList.size())
2391  {
2392  ossim_uint32 bandCount = GDALGetRasterCount(theDataset);
2393  for (ossim_uint32 i = 0; i < outputBandList.size(); i++)
2394  {
2395  if (outputBandList[i] > bandCount)//check if it is a valid band
2396  {
2397  return false;
2398  }
2399  }
2400  m_outputBandList = outputBandList; // Assign the new list.
2401  return true;
2402  }
2403  return false;
2404 }
2405 
2407 {
2408  bool stateChanged = (flag && !m_preservePaletteIndexesFlag);
2409 
2410  //---
2411  // Affects: ossimGdalTileSource::getNumberOfOutputBands
2412  // ossimGdalTileSource::getOutputScalarType
2413  //---
2415 
2416  if ( isOpen() && stateChanged )
2417  {
2418  //---
2419  // Already went through open so we must change the output tile from 3 band to 1 and the
2420  // output scalar type may have also changed.
2421  // Note the ossimImageDataFactory::create will call back to us for bands and scalr type
2422  // which have now changed.
2423  //---
2425  theTile->setIndexedFlag(true);
2426  theTile->initialize();
2427 
2431 
2433  {
2434  ossim_int32 nullIndex = theLut->getFirstNullAlphaIndex();
2435  if ( nullIndex > -1 ) // Returns -1 if not found.
2436  {
2437  // This will be used for fill in leiu of theTile->makeBlank().
2438  theLut->setNullPixelIndex(nullIndex);
2439  }
2440  }
2441  }
2442 }
2443 
2445 {
2447 }
2448 
2449 //---
2450 // Overrides ossimImageSource::isIndexedData to palette indicate we are passing palette indexes
2451 // not rgb pixel data down the stream.
2452 //---
2454 {
2456 }
2457 
2459 {
2460  // Look for the preserve_palette flag:
2461  const char* lookup = ossimPreferences::instance()->findPreference(PRESERVE_PALETTE_KW);
2462  if (lookup)
2463  {
2464  setPreservePaletteIndexesFlag(ossimString(lookup).toBool());
2465  }
2466 }
2468 {
2469  //ossimAppFixedTileCache::instance()->deleteCache(m_blockCacheId);
2470  ossim_uint32 idx = 0;
2471  for(idx = 0; idx < m_rlevelBlockCache.size();++idx)
2472  {
2474  }
2475  m_rlevelBlockCache.clear();
2476 }
2477 
2479 {
2480  if(m_isBlocked)
2481  {
2482  if(m_rlevelBlockCache.size() > 0) deleteRlevelCache();
2484  ossim_uint32 idx = 0;
2485  int xSize=0, ySize=0;
2486  m_rlevelBlockCache.resize(nLevels);
2487  for(idx =0; idx < nLevels; ++idx)
2488  {
2489  GDALGetBlockSize(resolveRasterBand( idx, 1 ),
2490  &xSize,
2491  &ySize);
2492  ossimIpt blockSize(xSize, ySize);
2493  ossimIrect rectBounds = getBoundingRect(idx);
2494  rectBounds.stretchToTileBoundary(blockSize);
2495  m_rlevelBlockCache[idx] = ossimAppFixedTileCache::instance()->newTileCache(rectBounds, blockSize);
2496  }
2497  }
2498 }
virtual void deleteCache(ossimAppFixedCacheId cacheId)
virtual void loadBand(const void *src, const ossimIrect &src_rect, ossim_uint32 band)
void setPreservePaletteIndexesFlag(bool flag)
Sets preserve palette indexes flag.
void clear()
Erases the entire container.
Definition: ossimString.h:432
virtual ossim_uint32 getWidth() const
ossim_uint32 x
virtual bool isSourceEnabled() const
Definition: ossimSource.cpp:79
virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level=0) const
Returns the zero based image rectangle for the reduced resolution data set (rrds) passed in...
static ossimImageGeometryRegistry * instance()
ossimRefPtr< ossimImageGeometry > theGeometry
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 ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if non defined...
void setProjection(ossimProjection *projection)
Sets the projection to be used for local-to-world coordinate transformation.
ossimFilename noExtension() const
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
virtual void setProperty(ossimRefPtr< ossimProperty > property)
Set propterty method.
std::basic_stringstream< char > stringstream
Class for char mixed input and output memory streams.
Definition: ossimIosFwd.h:38
64 bit floating point
static const char * DATUM_KW
virtual void getEntryNames(std::vector< ossimString > &entryStringList) const
ossimRefPtr< ossimImageData > theSingleBandTile
#define CLOG
Definition: ossimTrace.h:23
ossimFilename theImageFile
virtual void setImageRectangle(const ossimIrect &rect)
16 bit unsigned integer
ossimScalarType getInputScalarType() const
Gets the input scalar type of the tile source.
double getMinPix(ossim_uint32 band) const
ossim_uint32 getIndexBandOutputNumber(int bandNumber) const
ossimUnitType
Represents serializable keyword/value map.
bool addFile(const char *file)
ossim_uint32 y
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
std::vector< ossimDpt > theDecimationFactors
void setEntryLables(ossim_uint32 band, std::vector< ossimString > entryLabels)
virtual void getEntryNames(std::vector< ossimString > &entryNames) const
float ossim_float32
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 bool setOutputBandList(const std::vector< ossim_uint32 > &band_list)
If the image handler "isBandSeletor()" then the band selection of the output chip can be controlled...
void loadIndexTo3BandTileTemplate(InputType in, OutputType out, const ossimIrect &clipRect, ossim_uint32 aGdalBandStart=1, ossim_uint32 anOssimBandStart=0)
virtual ossim_uint32 getNumberOfLines(ossim_uint32 resLevel=0) const =0
Pure virtual, derived classes must implement.
This code was derived from https://gist.github.com/mshockwave.
Definition: Barrier.h:8
static const char * IMAGE_MODEL_TRANSFORM_MATRIX_KW
double y
Definition: ossimDpt.h:165
ossim_uint32 height() const
Definition: ossimIrect.h:487
bool contains(char aChar) const
Definition: ossimString.h:58
virtual ossimGpt inverse(const ossimDpt &pp) const
static ossimString toString(bool aValue)
Numeric to string methods.
virtual bool isGeographic() const
double getMaxPix(ossim_uint32 band) const
16 bit signed integer
const ossimIpt & ul() const
Definition: ossimIrect.h:274
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
virtual void getDecimationFactor(ossim_uint32 resLevel, ossimDpt &result) const
virtual ossim_int32 getEntryNumber(const char *entry_string, bool case_insensitive=true) const
virtual bool isOpen() const
Derived classes must implement this method to be concrete.
virtual ossim_uint32 getHeight() const
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
std::vector< ossimString > theSubDatasets
bool isIndexTo1Band(int bandNumber=1) const
ossim_uint32 toUInt32() const
virtual ossim_uint32 getNumberOfDecimationLevels() const
Returns the number of reduced resolution data sets (rrds).
virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level=0) const
Returns the number of bands in the image.
32 bit floating point
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
unsigned short ossim_uint16
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual ossim_uint32 getImageTileWidth() const
Returns the tile width of the image or 0 if the image is not tiled.
const ossimIpt & ll() const
Definition: ossimIrect.h:277
virtual double getMinPixelValue(ossim_uint32 band=0) const
Retuns the min pixel value.
32 bit unsigned integer
double getNullPix(ossim_uint32 band) const
static const char * TYPE_KW
virtual void initialize()
Initialize the data buffer.
ossim_uint32 getNumberOfBands() const
static ossimAppFixedTileCache * instance(ossim_uint32 maxSize=0)
virtual double optimizeFit(const ossimTieGptSet &tieSet, double *targetVariance=0)
ossimPixelType thePixelType
virtual ossim_uint32 getSizePerBandInBytes() const
Returns the number of bytes in single band of the tile.
virtual ossim_uint32 getNumberOfDecimationLevels() const
This returns the total number of decimation levels.
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
Get propterty names.
virtual bool isValidRLevel(ossim_uint32 resLevel) const
Determines if the passed in reslution level is valid.
virtual double getMinPixelValue(ossim_uint32 band=0) const
Retuns the min pixel value.
bool completely_within(const ossimIrect &rect) const
Definition: ossimIrect.cpp:425
static const char * PIXEL_SCALE_XY_KW
void push_back(char c)
Equivalent to insert(end(), c).
Definition: ossimString.h:905
virtual void getPropertyNames(std::vector< ossimString > &propertyNames) const
virtual void getEntryList(std::vector< ossim_uint32 > &entryList) const
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual void loadTile(const void *src, const ossimIrect &src_rect, ossimInterleaveType il_type)
vector< ossim_uint32 > m_outputBandList
OSSIM_DLL double defaultMin(ossimScalarType scalarType)
Definition: ossimCommon.cpp:73
ossimRefPtr< ossimImageData > getTileBlockRead(const ossimIrect &tileRect, ossim_uint32 resLevel)
bool getPreservePaletteIndexesFlag() const
static ossimImageDataFactory * instance()
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
ossimRefPtr< ossimImageData > getTile(ossimAppFixedCacheId cacheId, const ossimIpt &origin)
const char * findPreference(const char *key) const
virtual ossimDataObjectStatus validate() const
static const char * TIE_POINT_XY_KW
bool exists() const
void loadIndexTo3BandTile(const ossimIrect &clipRect, ossim_uint32 aGdalBandStart=1, ossim_uint32 anOssimBandStart=0)
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level=0) const
Returns the number of bands available from an image.
signed short ossim_sint16
virtual ossim_uint32 getNumberOfInputBands() const
Returns the number of bands in the image.
std::string::size_type size() const
Definition: ossimString.h:405
#define FLT_EPSILON
32 bit signed integer
bool toBool() const
String to numeric methods.
std::string::iterator begin()
Definition: ossimString.h:420
OSSIM_DLL double defaultNull(ossimScalarType scalarType)
virtual void nullTileAlpha(const ossim_uint8 *src, const ossimIrect &src_rect, bool mutliplyAlphaFlag=false)
ossim_uint32 getNumberOfEntries() const
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
bool isIndexTo3Band(int bandNumber=1) const
ossimRefPtr< ossimImageGeometry > getExternalImageGeometryFromXml() const
Class for FGDC XML doc parsing.
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
virtual ossimIrect getImageRectangle() const
GDALRasterBandH resolveRasterBand(ossim_uint32 resLevel, int gdalBandIndex) const
For the given resolution level and GDAL band index, return a corresponding GDAL raster band...
OSSIM_DLL ossim_uint32 scalarSizeInBytes(ossimScalarType scalarType)
virtual ossimScalarType getOutputScalarType() const
Returns the output pixel type of the tile source.
const ossimIpt & lr() const
Definition: ossimIrect.h:276
static const char * IMAGE_MODEL_TRANSFORM_UNIT_KW
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
virtual ossimIrect getImageRectangle(ossim_uint32 resLevel=0) const
Returns zero-based bounding rectangle of the image.
bool isBlocked(int band) const
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
Returns a pointer to a tile given an origin representing the upper left corner of the tile to grab fr...
virtual ossimString getShortName() const
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
void initImageParameters(ossimImageGeometry *geom) const
Convenience method to set things needed in the image geometry from the image handler.
ossimIrect clipToRect(const ossimIrect &rect) const
Definition: ossimIrect.cpp:501
virtual bool hasMetaData() const
static ossimPreferences * instance()
void setIndexedFlag(bool flag)
Sets the indexed flag.
const ossimIpt & ur() const
Definition: ossimIrect.h:275
std::vector< ossim_uint8 > theGdalBuffer
virtual ossim_uint32 getTileWidth() const
Returns the width of the output tile.
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
ossimScalarType
storage class for tie point between ground and image based on ossimGpt
Definition: ossimTieGpt.h:24
virtual ossimRefPtr< ossimImageGeometry > getInternalImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
virtual ossimString getLongName() const
static ossimProjectionFactoryRegistry * instance()
virtual const ossim_float64 * getMinPix() const
virtual bool isIndexedData() const
Indicated data is indexed.
virtual ossimRefPtr< ossimImageGeometry > getExternalImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
static const char * UNITS_KW
ossimRefPtr< ossimProjection > getProjection()
Gets projection from document.
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
virtual ossimScalarType getScalarType() const
virtual void makeBlank()
Initializes data to null pixel values.
virtual ossim_uint32 getTileHeight() const
Returns the height of the output tile.
virtual void completeOpen()
Will complete the opening process.
void addTiePoint(ossimRefPtr< ossimTieGpt > aTiePt)
operations
ossim_uint32 theEntryNumberToRender
std::vector< ossimAppFixedTileCache::ossimAppFixedCacheId > m_rlevelBlockCache
ossimImageMetaData theMetaData
ossimString toString(ossim_uint32 precision=15) const
Definition: ossimDpt.cpp:160
OSSIM_DLL double defaultMax(ossimScalarType scalarType)
ossimRefPtr< ossimImageHandler > theOverview
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual ossimRefPtr< ossimProperty > getProperty(const ossimString &name) const
Get propterty method.
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
ossim_int32 y
Definition: ossimIpt.h:142
storage class for a set of geographic tie points, between master and slave images ...
virtual void close()
Deletes the overview and clears the valid image vertices.
void makeNan()
Definition: ossimIrect.h:329
virtual const void * getBuf() const
void setNullPixelIndex(ossim_int32 idx)
Allows you to specify which entry is to be designated as an invalid entry.
double x
Definition: ossimDpt.h:164
virtual ossim_uint32 getCurrentEntry() const
long long ossim_int64
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool empty() const
Definition: ossimString.h:411
class ossimNBandLutDataObject
void stretchToTileBoundary(const ossimIpt &tileWidthHeight)
Definition: ossimIrect.cpp:212
ossimFilename theOverviewFile
bool hasNans() const
Definition: ossimIrect.h:337
virtual ossim_uint32 getImageTileHeight() const
Returns the tile width of the image or 0 if the image is not tiled.
bool open(const ossimFilename &xmlFileName)
Open method.
ossim_int32 getNullPixelIndex() const
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
Returns zero-based bounding rectangle of the image.
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
ossim_int32 x
Definition: ossimIpt.h:141
bool toOssimKwl(const ossimString &wktString, ossimKeywordlist &kwl, const char *prefix=NULL) const
virtual double getMaxPixelValue(ossim_uint32 band=0) const
Returns the max pixel of the band.
ossimRefPtr< ossimNBandLutDataObject > theLut
8 bit unsigned integer
virtual ossimString getClassName() const
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
bool isIndexed(int aGdalBandNumber=1) const
ossimRefPtr< ossimImageData > theTile
virtual void setScalarType(ossimScalarType type)
See ossimScalarType in ossimConstants for a full list.
32 bit floating point
static ossimUnitTypeLut * instance()
Returns the static instance of an ossimUnitTypeLut object.
ossimAppFixedCacheId newTileCache(const ossimIrect &tileBoundaryRect, const ossimIpt &tileSize=ossimIpt(0, 0))
void getDefaults()
Checks prefences for default settings.
ossim_int32 getFirstNullAlphaIndex() const
virtual double getNullPixelValue(ossim_uint32 band=0) const
Each band has a null pixel associated with it.
ossimFilename path() const
void getMaxSize(ossim_uint32 resLevel, int &maxX, int &maxY) const
16 bit unsigned iteger
64 bit floating point
16 bit signed integer
unsigned char ossim_uint8
virtual bool setCurrentEntry(ossim_uint32 entryIdx)
ossimRefPtr< ossimImageData > addTile(ossimAppFixedCacheId cacheId, ossimRefPtr< ossimImageData > data, bool duplicateData=true)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
static const char * PIXEL_SCALE_UNITS_KW
static const char * TIE_POINT_UNITS_KW
const ossimString & getName() const
int ossim_int32
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
ossimString filterSubDatasetsString(const ossimString &subString) const
Filters string from "GDALGetMetadata( theDataset, "SUBDATASETS" )