[QGIS Commit] r14650 - in branches/raster-providers/src: core core/raster providers/gdal providers/grass

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun Nov 14 13:14:57 EST 2010


Author: rblazek
Date: 2010-11-14 10:14:56 -0800 (Sun, 14 Nov 2010)
New Revision: 14650

Modified:
   branches/raster-providers/src/core/qgsrasterdataprovider.cpp
   branches/raster-providers/src/core/qgsrasterdataprovider.h
   branches/raster-providers/src/core/raster/qgsrasterlayer.cpp
   branches/raster-providers/src/core/raster/qgsrasterlayer.h
   branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp
   branches/raster-providers/src/providers/gdal/qgsgdalprovider.h
   branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp
   branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h
Log:
remaining gdal to gdal provider, gdal and grass mostly working

Modified: branches/raster-providers/src/core/qgsrasterdataprovider.cpp
===================================================================
--- branches/raster-providers/src/core/qgsrasterdataprovider.cpp	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/core/qgsrasterdataprovider.cpp	2010-11-14 18:14:56 UTC (rev 14650)
@@ -121,10 +121,9 @@
 }
 
 //void QgsRasterDataProvider::buildSupportedRasterFileFilter( QString & theFileFiltersString ) 
-void QgsRasterDataProvider::buildSupportedRasterFileFilter( QString & theFileFiltersString ) 
-{ 
-  QgsDebugMsg ( "Entered" );  
-};
+//{ 
+  //QgsDebugMsg ( "Entered" );  
+//};
 
 
 

Modified: branches/raster-providers/src/core/qgsrasterdataprovider.h
===================================================================
--- branches/raster-providers/src/core/qgsrasterdataprovider.h	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/core/qgsrasterdataprovider.h	2010-11-14 18:14:56 UTC (rev 14650)
@@ -25,10 +25,17 @@
 #include "qgsrectangle.h"
 #include "qgsdataprovider.h"
 #include "qgscolorrampshader.h"
+#include "qgsrasterpyramid.h"
 
+#include <cmath>
+
 class QImage;
 class QgsPoint;
+class QgsRasterBandStats;
 
+#define TINY_VALUE  std::numeric_limits<double>::epsilon() * 20
+
+
 /** \ingroup core
  * Base class for raster data providers.
  *
@@ -203,10 +210,76 @@
     }
 
     /** Returns data type for the band specified by number */
-    virtual int colorInterpretation ( int bandNo ) const {
+    virtual int colorInterpretation ( int theBandNo ) const {
       return QgsRasterDataProvider::UndefinedColorInterpretation;
     }
 
+    QString colorName ( int colorInterpretation ) const {
+      // Modified copy from GDAL
+      switch( colorInterpretation )
+      {
+        case UndefinedColorInterpretation:
+          return "Undefined";
+
+        case GrayIndex:
+          return "Gray";
+
+        case PaletteIndex:
+          return "Palette";
+
+        case RedBand:
+          return "Red";
+
+        case GreenBand:
+          return "Green";
+
+        case BlueBand:
+          return "Blue";
+
+        case AlphaBand:
+          return "Alpha";
+
+        case HueBand:
+          return "Hue";
+
+        case SaturationBand:
+          return "Saturation";
+
+        case LightnessBand:
+          return "Lightness";
+
+        case CyanBand:
+          return "Cyan";
+
+        case MagentaBand:
+          return "Magenta";
+
+        case YellowBand:
+          return "Yellow";
+
+        case BlackBand:
+          return "Black";
+
+        case YCbCr_YBand:
+          return "YCbCr_Y";
+
+        case YCbCr_CbBand:
+          return "YCbCr_Cb";
+
+        case YCbCr_CrBand:
+          return "YCbCr_Cr";
+
+        default:
+          return "Unknown";
+      }
+    }
+    /** Reload data (data could change) */
+    virtual bool reload ( ) { return true; }
+
+    virtual QString colorInterpretationName ( int theBandNo ) const {
+      return colorName ( colorInterpretation ( theBandNo ) );
+    }
+
     /** Get block size */
     virtual int xBlockSize() const { return 0; }
     virtual int yBlockSize() const { return 0; }
@@ -230,6 +303,39 @@
 
     virtual QList<QgsColorRampShader::ColorRampItem> colorTable(int bandNo)const { return QList<QgsColorRampShader::ColorRampItem>(); }
 
+    // Defined in parent
+    /** \brief Returns the sublayers of this layer - Useful for providers that manage their own layers, such as WMS */
+    //virtual QStringList subLayers() const ;
+
+    /** \brief Populate the histogram vector for a given band */
+
+    virtual void populateHistogram( int theBandNoInt,
+                    QgsRasterBandStats & theBandStats,
+                    int theBinCountInt = 256,
+                    bool theIgnoreOutOfRangeFlag = true,
+                    bool theThoroughBandScanFlag = false
+                ) {};
+
+    /** \brief Create pyramid overviews */
+    QString buildPyramids( const QList<QgsRasterPyramid>  & thePyramidList,
+                           const QString &  theResamplingMethod = "NEAREST",
+                           bool theTryInternalFlag = false ) { return "FAILED_NOT_SUPPORTED"; };
+
+    /** \brief Accessor for ths raster layers pyramid list. A pyramid list defines the
+     * POTENTIAL pyramids that can be in a raster. To know which of the pyramid layers
+     * ACTUALLY exists you need to look at the existsFlag member in each struct stored in the
+     * list.
+     */
+    QList<QgsRasterPyramid> buildPyramidList() { return QList<QgsRasterPyramid>(); };
+
+
+    /** \brief helper function to create zero padded band names */
+    QString  generateBandName( int theBandNumber ) 
+    {
+      return tr( "Band" ) + QString( " %1" ) .arg( theBandNumber,  1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) );
+    }
+
+
     /**
      * Get metadata in a format suitable for feeding directly
      * into a subset of the GUI raster properties "Metadata" tab.
@@ -300,7 +406,19 @@
      */
     virtual QString lastErrorFormat();
 
+    //virtual void buildSupportedRasterFileFilter( QString & theFileFiltersString ) ;
 
+    /** This helper checks to see whether the file name appears to be a valid
+     *  raster file name.  If the file name looks like it could be valid,
+     *  but some sort of error occurs in processing the file, the error is
+     *  returned in retError.
+     */
+
+    //virtual bool isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg ) { return false; } ;
+
+    //virtual bool isValidRasterFileName( const QString & theFileNameQString ) { return false; };
+
+
     /**Returns the dpi of the output device.
       @note: this method was added in version 1.2*/
     int dpi() const {return mDpi;}
@@ -312,7 +430,6 @@
     /** \brief Is the NoDataValue Valid */
     bool isNoDataValueValid() const { return mValidNoDataValue; }
 
-    void buildSupportedRasterFileFilter( QString & theFileFiltersString ) ;
 
 
     static QStringList cStringList2Q_( char ** stringList );

Modified: branches/raster-providers/src/core/raster/qgsrasterlayer.cpp
===================================================================
--- branches/raster-providers/src/core/raster/qgsrasterlayer.cpp	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/core/raster/qgsrasterlayer.cpp	2010-11-14 18:14:56 UTC (rev 14650)
@@ -60,6 +60,11 @@
 #include <QSlider>
 #include <QSettings>
 #include "qgslogger.h"
+
+// typedefs for provider plugin functions of interest
+typedef void buildsupportedrasterfilefilter_t( QString & theFileFiltersString );
+typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QString & retErrMsg );
+
 // workaround for MSVC compiler which already has defined macro max
 // that interferes with calling std::numeric_limits<int>::max
 #ifdef _MSC_VER
@@ -184,18 +189,20 @@
 void QgsRasterLayer::buildSupportedRasterFileFilter( QString & theFileFiltersString )
 {
   QgsDebugMsg( "Entered" );
-  QgsRasterDataProvider *myDataProvider = QgsRasterLayer::loadProvider ( "gdal" );
-  if ( !myDataProvider ) 
+  QLibrary*  myLib = QgsRasterLayer::loadProviderLibrary( "gdal" );
+  if ( !myLib ) 
   {
-    QgsDebugMsg( "Could not createe gdal provider" );
+    QgsDebugMsg( "Could not load gdal provider library" );
     return;
   }
-  myDataProvider->buildSupportedRasterFileFilter( theFileFiltersString );
+  buildsupportedrasterfilefilter_t *pBuild = ( buildsupportedrasterfilefilter_t * ) cast_to_fptr( myLib->resolve( "buildSupportedRasterFileFilter" ) );
+  if ( ! pBuild ) {
+    QgsDebugMsg( "Could not resolve buildSupportedRasterFileFilter in gdal provider library");
+    return;
+  }
   
-  // crash
-  //delete myDataProvider;
-  QgsDebugMsg( "file filter: " + theFileFiltersString );
-  exit(0);
+  pBuild( theFileFiltersString );
+  delete myLib;
 }
 
 /**
@@ -203,38 +210,22 @@
  */
 bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg )
 {
-  GDALDatasetH myDataset;
-
-  // TODO
-  return true;
-
-  CPLErrorReset();
-
-  //open the file using gdal making sure we have handled locale properly
-  myDataset = GDALOpen( QFile::encodeName( theFileNameQString ).constData(), GA_ReadOnly );
-  if ( myDataset == NULL )
+  
+  QLibrary*  myLib = QgsRasterLayer::loadProviderLibrary( "gdal");
+  if ( !myLib ) 
   {
-    if ( CPLGetLastErrorNo() != CPLE_OpenFailed )
-      retErrMsg = QString::fromUtf8( CPLGetLastErrorMsg() );
+    QgsDebugMsg( "Could not load gdal provider library" );
     return false;
   }
-  else if ( GDALGetRasterCount( myDataset ) == 0 )
-  {
-    QStringList layers = subLayers( myDataset );
-    if ( layers.size() == 0 )
-    {
-      GDALClose( myDataset );
-      myDataset = NULL;
-      retErrMsg = tr( "This raster file has no bands and is invalid as a raster layer." );
-      return false;
-    }
-    return true;
+  isvalidrasterfilename_t *pValid = ( isvalidrasterfilename_t * ) cast_to_fptr( myLib->resolve( "isValidRasterFileName" ) );
+  if ( ! pValid ) {
+    QgsDebugMsg( "Could not resolve isValidRasterFileName in gdal provider library");
+    return false;
   }
-  else
-  {
-    GDALClose( myDataset );
-    return true;
-  }
+  
+  bool myIsValid = pValid( theFileNameQString, retErrMsg  );
+  delete myLib;
+  return myIsValid;
 }
 
 bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString )
@@ -386,7 +377,6 @@
   QgsDebugMsg( "theBandNo = " + QString::number(theBandNo) );
   QgsDebugMsg( "mRasterType = " + QString::number(mRasterType) );
   // check if we have received a valid band number
-  //if (( GDALGetRasterCount( mGdalDataset ) < theBandNo ) && mRasterType != Palette )
   if (( mDataProvider->bandCount() < theBandNo ) && mRasterType != Palette )
   {
     // invalid band id, return nothing
@@ -420,92 +410,29 @@
   emit statusChanged( tr( "Retrieving stats for %1" ).arg( name() ) );
   qApp->processEvents();
   QgsDebugMsg( "stats for band " + QString::number( theBandNo ) );
-  //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
 
-  // Not used
-  //QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
-
-  // XXX this sets the element count to a sensible value; but then you ADD to
-  // XXX it later while iterating through all the pixels?
-  //myRasterBandStats.elementCount = mWidth * mHeight;
-
   myRasterBandStats.elementCount = 0; // because we'll be counting only VALID pixels later
 
   emit statusChanged( tr( "Calculating stats for %1" ).arg( name() ) );
   //reset the main app progress bar
   emit drawingProgress( 0, 0 );
 
-  // let the user know we're going to possibly be taking a while
-  //QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-
-  //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
   int myDataType = mDataProvider->dataType ( theBandNo );
 
   int  myNXBlocks, myNYBlocks, myXBlockSize, myYBlockSize;
-  //GDALGetBlockSize( myGdalBand, &myXBlockSize, &myYBlockSize );
   myXBlockSize = mDataProvider->xBlockSize();
   myYBlockSize = mDataProvider->yBlockSize();
 
-  //myNXBlocks = ( GDALGetRasterXSize( myGdalBand ) + myXBlockSize - 1 ) / myXBlockSize;
-  //myNYBlocks = ( GDALGetRasterYSize( myGdalBand ) + myYBlockSize - 1 ) / myYBlockSize;
-
   myNXBlocks = ( mDataProvider->xSize() + myXBlockSize - 1 ) / myXBlockSize;
   myNYBlocks = ( mDataProvider->ySize() + myYBlockSize - 1 ) / myYBlockSize;
 
-  //void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( GDALGetDataTypeSize( myDataType ) / 8 ) );
   void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( mDataProvider->dataTypeSize(theBandNo ) / 8 ) );
 
   // unfortunately we need to make two passes through the data to calculate stddev
   bool myFirstIterationFlag = true;
 
-  //ifdefs below to remove compiler warning about unused vars
-#ifdef QGISDEBUG
-/*
-  int success;
-  double GDALminimum = GDALGetRasterMinimum( myGdalBand, &success );
-
-  if ( ! success )
-  {
-    QgsDebugMsg( "myGdalBand->GetMinimum() failed" );
-  }
-
-  double GDALmaximum = GDALGetRasterMaximum( myGdalBand, &success );
-
-  if ( ! success )
-  {
-    QgsDebugMsg( "myGdalBand->GetMaximum() failed" );
-  }
-
-  double GDALnodata = GDALGetRasterNoDataValue( myGdalBand, &success );
-
-  if ( ! success )
-  {
-    QgsDebugMsg( "myGdalBand->GetNoDataValue() failed" );
-  }
-
-  QgsLogger::debug( "GDALminium: ", GDALminimum, __FILE__, __FUNCTION__, __LINE__ );
-  QgsLogger::debug( "GDALmaximum: ", GDALmaximum, __FILE__, __FUNCTION__, __LINE__ );
-  QgsLogger::debug( "GDALnodata: ", GDALnodata, __FILE__, __FUNCTION__, __LINE__ );
-
-  double GDALrange[2];          // calculated min/max, as opposed to the
-  // dataset provided
-
-  GDALComputeRasterMinMax( myGdalBand, 1, GDALrange );
-  QgsLogger::debug( "approximate computed GDALminium:", GDALrange[0], __FILE__, __FUNCTION__, __LINE__, 1 );
-  QgsLogger::debug( "approximate computed GDALmaximum:", GDALrange[1], __FILE__, __FUNCTION__, __LINE__, 1 );
-
-  GDALComputeRasterMinMax( myGdalBand, 0, GDALrange );
-  QgsLogger::debug( "exactly computed GDALminium:", GDALrange[0] );
-  QgsLogger::debug( "exactly computed GDALmaximum:", GDALrange[1] );
-
-  QgsDebugMsg( "starting manual stat computation" );
-*/
-#endif
-
-  //int myGdalBandXSize = GDALGetRasterXSize( myGdalBand );
-  //int myGdalBandYSize = GDALGetRasterYSize( myGdalBand );
-  int myGdalBandXSize = mDataProvider->xSize();
-  int myGdalBandYSize = mDataProvider->ySize();
+  int myBandXSize = mDataProvider->xSize();
+  int myBandYSize = mDataProvider->ySize();
   for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
   {
     emit drawingProgress( iYBlock, myNYBlocks * 2 );
@@ -513,18 +440,17 @@
     for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
     {
       int  nXValid, nYValid;
-      //GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
       mDataProvider->readBlock( theBandNo, iXBlock, iYBlock, myData );
 
       // Compute the portion of the block that is valid
       // for partial edge blocks.
-      if (( iXBlock + 1 ) * myXBlockSize > myGdalBandXSize )
-        nXValid = myGdalBandXSize - iXBlock * myXBlockSize;
+      if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
+        nXValid = myBandXSize - iXBlock * myXBlockSize;
       else
         nXValid = myXBlockSize;
 
-      if (( iYBlock + 1 ) * myYBlockSize > myGdalBandYSize )
-        nYValid = myGdalBandYSize - iYBlock * myYBlockSize;
+      if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
+        nYValid = myBandYSize - iYBlock * myYBlockSize;
       else
         nYValid = myYBlockSize;
 
@@ -534,7 +460,7 @@
         for ( int iX = 0; iX < nXValid; iX++ )
         {
           double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
-          QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (iX).arg(iY).arg( myValue ) );
+          //QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (iX).arg(iY).arg( myValue ) );
 
           if ( mValidNoDataValue && ( fabs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
           {
@@ -583,18 +509,17 @@
     {
       int  nXValid, nYValid;
 
-      //GDALReadBlock( myGdalBand, iXBlock, iYBlock, myData );
       mDataProvider->readBlock( theBandNo, iXBlock, iYBlock, myData );
 
       // Compute the portion of the block that is valid
       // for partial edge blocks.
-      if (( iXBlock + 1 ) * myXBlockSize > myGdalBandXSize )
-        nXValid = myGdalBandXSize - iXBlock * myXBlockSize;
+      if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
+        nXValid = myBandXSize - iXBlock * myXBlockSize;
       else
         nXValid = myXBlockSize;
 
-      if (( iYBlock + 1 ) * myYBlockSize > myGdalBandYSize )
-        nYValid = myGdalBandYSize - iYBlock * myYBlockSize;
+      if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
+        nYValid = myBandYSize - iYBlock * myYBlockSize;
       else
         nYValid = myYBlockSize;
 
@@ -651,7 +576,7 @@
 
   //we cant use a vector iterator because the iterator is astruct not a class
   //and the qvector model does not like this.
-  for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
+  for ( int i = 1; i <= mDataProvider->bandCount(); i++ )
   {
     QgsRasterBandStats myRasterBandStats = bandStatistics( i );
     if ( myRasterBandStats.bandName == theBandName )
@@ -664,254 +589,16 @@
 }
 
 
-/*
- * This will speed up performance at the expense of hard drive space.
- * Also, write access to the file is required for creating internal pyramids,
- * and to the directory in which the files exists if external
- * pyramids (.ovr) are to be created. If no parameter is passed in
- * it will default to nearest neighbor resampling.
- *
- * @param theTryInternalFlag - Try to make the pyramids internal if supported (e.g. geotiff). If not supported it will revert to creating external .ovr file anyway.
- * @return null string on success, otherwise a string specifying error
- */
 QString QgsRasterLayer::buildPyramids( RasterPyramidList const & theRasterPyramidList,
                                        QString const & theResamplingMethod, bool theTryInternalFlag )
 {
-  //TODO: Consider making theRasterPyramidList modifyable by this method to indicate if the pyramid exists after build attempt
-  //without requiring the user to rebuild the pyramid list to get the updated infomation
-
-  //
-  // Note: Make sure the raster is not opened in write mode
-  // in order to force overviews to be written to a separate file.
-  // Otherwise reoopen it in read/write mode to stick overviews
-  // into the same file (if supported)
-  //
-
-
-  emit drawingProgress( 0, 0 );
-  //first test if the file is writeable
-  QFileInfo myQFile( mDataSource );
-
-  if ( !myQFile.isWritable() )
-  {
-    return "ERROR_WRITE_ACCESS";
-  }
-
-  if ( mGdalDataset != mGdalBaseDataset )
-  {
-    QgsLogger::warning( "Pyramid building not currently supported for 'warped virtual dataset'." );
-    return "ERROR_VIRTUAL";
-  }
-
-  if ( theTryInternalFlag )
-  {
-    // libtiff < 4.0 has a bug that prevents safe building of overviews on JPEG compressed files
-    // we detect libtiff < 4.0 by checking that BIGTIFF is not in the creation options of the GTiff driver
-    // see https://trac.osgeo.org/qgis/ticket/1357
-    const char* pszGTiffCreationOptions =
-      GDALGetMetadataItem( GDALGetDriverByName( "GTiff" ), GDAL_DMD_CREATIONOPTIONLIST, "" );
-    if ( strstr( pszGTiffCreationOptions, "BIGTIFF" ) == NULL )
-    {
-      QString myCompressionType = QString( GDALGetMetadataItem( mGdalDataset, "COMPRESSION", "IMAGE_STRUCTURE" ) );
-      if ( "JPEG" == myCompressionType )
-      {
-        return "ERROR_JPEG_COMPRESSION";
-      }
-    }
-
-    //close the gdal dataset and reopen it in read / write mode
-    GDALClose( mGdalDataset );
-    mGdalBaseDataset = GDALOpen( QFile::encodeName( mDataSource ).constData(), GA_Update );
-
-    // if the dataset couldn't be opened in read / write mode, tell the user
-    if ( !mGdalBaseDataset )
-    {
-      mGdalBaseDataset = GDALOpen( QFile::encodeName( mDataSource ).constData(), GA_ReadOnly );
-      //Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
-      mGdalDataset = mGdalBaseDataset;
-      return "ERROR_WRITE_FORMAT";
-    }
-  }
-
-  //
-  // Iterate through the Raster Layer Pyramid Vector, building any pyramid
-  // marked as exists in eaxh RasterPyramid struct.
-  //
-  CPLErr myError; //in case anything fails
-  int myCount = 1;
-  int myTotal = theRasterPyramidList.count();
-  RasterPyramidList::const_iterator myRasterPyramidIterator;
-  for ( myRasterPyramidIterator = theRasterPyramidList.begin();
-        myRasterPyramidIterator != theRasterPyramidList.end();
-        ++myRasterPyramidIterator )
-  {
-#ifdef QGISDEBUG
-    QgsLogger::debug( "Build pyramids:: Level", ( *myRasterPyramidIterator ).level, 1, __FILE__, __FUNCTION__, __LINE__ );
-    QgsLogger::debug( "x", ( *myRasterPyramidIterator ).xDim, 1, __FILE__, __FUNCTION__, __LINE__ );
-    QgsLogger::debug( "y", ( *myRasterPyramidIterator ).yDim, 1, __FILE__, __FUNCTION__, __LINE__ );
-    QgsLogger::debug( "exists :", ( *myRasterPyramidIterator ).exists,  1, __FILE__, __FUNCTION__, __LINE__ );
-#endif
-    if (( *myRasterPyramidIterator ).build )
-    {
-      QgsDebugMsg( "Building....." );
-      emit drawingProgress( myCount, myTotal );
-      int myOverviewLevelsArray[1] = {( *myRasterPyramidIterator ).level };
-      /* From : http://remotesensing.org/gdal/classGDALDataset.html#a23
-       * pszResampling : one of "NEAREST", "AVERAGE" or "MODE" controlling the downsampling method applied.
-       * nOverviews : number of overviews to build.
-       * panOverviewList : the list of overview decimation factors to build.
-       * nBand : number of bands to build overviews for in panBandList. Build for all bands if this is 0.
-       * panBandList : list of band numbers.
-       * pfnProgress : a function to call to report progress, or NULL.
-       * pProgressData : application data to pass to the progress function.
-       */
-      //build the pyramid and show progress to console
-      try
-      {
-
-        //build the pyramid and show progress to console
-        //NOTE this (magphase) is disabled in the gui since it tends
-        //to create corrupted images. The images can be repaired
-        //by running one of the other resampling strategies below.
-        //see ticket #284
-        if ( theResamplingMethod == tr( "Average Magphase" ) )
-        {
-          myError = GDALBuildOverviews( mGdalBaseDataset, "MODE", 1, myOverviewLevelsArray, 0, NULL,
-                                        progressCallback, this ); //this is the arg for the gdal progress callback
-        }
-        else if ( theResamplingMethod == tr( "Average" ) )
-
-        {
-          myError = GDALBuildOverviews( mGdalBaseDataset, "AVERAGE", 1, myOverviewLevelsArray, 0, NULL,
-                                        progressCallback, this ); //this is the arg for the gdal progress callback
-        }
-        else // fall back to nearest neighbor
-        {
-          myError = GDALBuildOverviews( mGdalBaseDataset, "NEAREST", 1, myOverviewLevelsArray, 0, NULL,
-                                        progressCallback, this ); //this is the arg for the gdal progress callback
-        }
-
-        if ( myError == CE_Failure || CPLGetLastErrorNo() == CPLE_NotSupported )
-        {
-          //something bad happenend
-          //QString myString = QString (CPLGetLastError());
-          GDALClose( mGdalBaseDataset );
-          mGdalBaseDataset = GDALOpen( QFile::encodeName( mDataSource ).constData(), GA_ReadOnly );
-          //Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
-          mGdalDataset = mGdalBaseDataset;
-
-          emit drawingProgress( 0, 0 );
-          return "FAILED_NOT_SUPPORTED";
-        }
-        else
-        {
-          //make sure the raster knows it has pyramids
-          mHasPyramids = true;
-        }
-        myCount++;
-
-      }
-      catch ( CPLErr )
-      {
-        QgsLogger::warning( "Pyramid overview building failed!" );
-      }
-    }
-  }
-
-  QgsDebugMsg( "Pyramid overviews built" );
-  if ( theTryInternalFlag )
-  {
-    //close the gdal dataset and reopen it in read only mode
-    GDALClose( mGdalBaseDataset );
-    mGdalBaseDataset = GDALOpen( QFile::encodeName( mDataSource ).constData(), GA_ReadOnly );
-    //Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
-    mGdalDataset = mGdalBaseDataset;
-  }
-
-  emit drawingProgress( 0, 0 );
-  return NULL; // returning null on success
+  return mDataProvider->buildPyramids(  theRasterPyramidList, theResamplingMethod, theTryInternalFlag );
 }
 
 
 QgsRasterLayer::RasterPyramidList  QgsRasterLayer::buildPyramidList()
 {
-  //
-  // First we build up a list of potential pyramid layers
-  //
-  int myWidth = mWidth;
-  int myHeight = mHeight;
-  int myDivisor = 2;
-
-  if ( mDataProvider ) return mPyramidList;
-
-  GDALRasterBandH myGDALBand = GDALGetRasterBand( mGdalDataset, 1 ); //just use the first band
-
-  mPyramidList.clear();
-  QgsDebugMsg( "Building initial pyramid list" );
-  while (( myWidth / myDivisor > 32 ) && (( myHeight / myDivisor ) > 32 ) )
-  {
-
-    QgsRasterPyramid myRasterPyramid;
-    myRasterPyramid.level = myDivisor;
-    myRasterPyramid.xDim = ( int )( 0.5 + ( myWidth / ( double )myDivisor ) );
-    myRasterPyramid.yDim = ( int )( 0.5 + ( myHeight / ( double )myDivisor ) );
-    myRasterPyramid.exists = false;
-#ifdef QGISDEBUG
-    QgsLogger::debug( "Pyramid", myRasterPyramid.level, 1, __FILE__, __FUNCTION__, __LINE__ );
-    QgsLogger::debug( "xDim", myRasterPyramid.xDim, 1, __FILE__, __FUNCTION__, __LINE__ );
-    QgsLogger::debug( "yDim", myRasterPyramid.yDim, 1, __FILE__, __FUNCTION__, __LINE__ );
-#endif
-
-    //
-    // Now we check if it actually exists in the raster layer
-    // and also adjust the dimensions if the dimensions calculated
-    // above are only a near match.
-    //
-    const int myNearMatchLimit = 5;
-    if ( GDALGetOverviewCount( myGDALBand ) > 0 )
-    {
-      int myOverviewCount;
-      for ( myOverviewCount = 0;
-            myOverviewCount < GDALGetOverviewCount( myGDALBand );
-            ++myOverviewCount )
-      {
-        GDALRasterBandH myOverview;
-        myOverview = GDALGetOverview( myGDALBand, myOverviewCount );
-        int myOverviewXDim = GDALGetRasterBandXSize( myOverview );
-        int myOverviewYDim = GDALGetRasterBandYSize( myOverview );
-        //
-        // here is where we check if its a near match:
-        // we will see if its within 5 cells either side of
-        //
-        QgsDebugMsg( "Checking whether " + QString::number( myRasterPyramid.xDim ) + " x " +
-                     QString::number( myRasterPyramid.yDim ) + " matches " +
-                     QString::number( myOverviewXDim ) + " x " + QString::number( myOverviewYDim ) );
-
-
-        if (( myOverviewXDim <= ( myRasterPyramid.xDim + myNearMatchLimit ) ) &&
-            ( myOverviewXDim >= ( myRasterPyramid.xDim - myNearMatchLimit ) ) &&
-            ( myOverviewYDim <= ( myRasterPyramid.yDim + myNearMatchLimit ) ) &&
-            ( myOverviewYDim >= ( myRasterPyramid.yDim - myNearMatchLimit ) ) )
-        {
-          //right we have a match so adjust the a / y before they get added to the list
-          myRasterPyramid.xDim = myOverviewXDim;
-          myRasterPyramid.yDim = myOverviewYDim;
-          myRasterPyramid.exists = true;
-          QgsDebugMsg( ".....YES!" );
-        }
-        else
-        {
-          //no match
-          QgsDebugMsg( ".....no." );
-        }
-      }
-    }
-    mPyramidList.append( myRasterPyramid );
-    //sqare the divisor each step
-    myDivisor = ( myDivisor * 2 );
-  }
-
-  return mPyramidList;
+  return mDataProvider->buildPyramidList();
 }
 
 QString QgsRasterLayer::colorShadingAlgorithmAsString() const
@@ -947,8 +634,8 @@
 
   if ( 0 < theBand && theBand <= ( int ) bandCount() )
   {
-    GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBand );
-    GDALComputeRasterMinMax( myGdalBand, 1, theMinMax );
+    theMinMax[0] = mDataProvider->minimumValue(theBand);
+    theMinMax[1] = mDataProvider->maximumValue(theBand);
   }
 }
 
@@ -977,15 +664,11 @@
 {
   if ( 0 == theMinMax ) { return; }
 
-  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBand );
-  //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
   int myDataType = mDataProvider->dataType( theBand );
-  // TODO
-  //void* myGdalScanData = readData( myGdalBand, &mLastViewPort );
-  void* myGdalScanData = NULL;
+  void* myScanData = readData( theBand, &mLastViewPort );
 
   /* Check for out of memory error */
-  if ( myGdalScanData == NULL )
+  if ( myScanData == NULL )
   {
     return;
   }
@@ -999,7 +682,7 @@
     {
       for ( int myColumn = 0; myColumn < mLastViewPort.drawableAreaXDim; ++myColumn )
       {
-        myValue = readValue( myGdalScanData, myDataType, myRow * mLastViewPort.drawableAreaXDim + myColumn );
+        myValue = readValue( myScanData, myDataType, myRow * mLastViewPort.drawableAreaXDim + myColumn );
         if ( mValidNoDataValue && ( fabs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
         {
           continue;
@@ -1635,84 +1318,11 @@
 bool QgsRasterLayer::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
 {
   theResults.clear();
-  if ( mProviderKey == "wms" )
-  {
-    return false;
-  }
 
-  QgsDebugMsg( thePoint.toString() );
+  QgsDebugMsg( "identify provider : " + mProviderKey ) ;
+  return ( mDataProvider->identify( thePoint, theResults ) );
+} 
 
-  if ( !mProviderKey.isEmpty() )
-  {
-    QgsDebugMsg( "identify provider : " + mProviderKey ) ;
-    return ( mDataProvider->identify( thePoint, theResults ) );
-  }
-
-  if ( !mLayerExtent.contains( thePoint ) )
-  {
-    // Outside the raster
-    for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
-    {
-      theResults[ generateBandName( i )] = tr( "out of extent" );
-    }
-  }
-  else
-  {
-    double x = thePoint.x();
-    double y = thePoint.y();
-
-    /* Calculate the row / column where the point falls */
-    double xres = ( mLayerExtent.xMaximum() - mLayerExtent.xMinimum() ) / mWidth;
-    double yres = ( mLayerExtent.yMaximum() - mLayerExtent.yMinimum() ) / mHeight;
-
-    // Offset, not the cell index -> flor
-    int col = ( int ) floor(( x - mLayerExtent.xMinimum() ) / xres );
-    int row = ( int ) floor(( mLayerExtent.yMaximum() - y ) / yres );
-
-    QgsDebugMsg( "row = " + QString::number( row ) + " col = " + QString::number( col ) );
-
-    //for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
-    for ( int i = 1; i <= mDataProvider->bandCount(); i++ )
-    {
-      //GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, i );
-      //GDALDataType type = GDALGetRasterDataType( gdalBand );
-      //int size = GDALGetDataTypeSize( type ) / 8;
-      int size = mDataProvider->dataTypeSize(i)/8;
-      void *data = CPLMalloc( size );
-
-      // TODO
-      //CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, 1, 1,
-                                 //data, 1, 1, type, 0, 0 );
-
-      //if ( err != CPLE_None )
-      //{
-        //QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
-      //}
-
-      //double value = readValue( data, type, 0 );
-//#ifdef QGISDEBUG
-      //QgsLogger::debug( "value", value, 1, __FILE__, __FUNCTION__, __LINE__ );
-//#endif
-      //QString v;
-
-      //if ( mValidNoDataValue && ( fabs( value - mNoDataValue ) <= TINY_VALUE || value != value ) )
-      //{
-        //v = tr( "null (no data)" );
-      //}
-      //else
-      //{
-        //v.setNum( value );
-      //}
-
-      //theResults[ generateBandName( i )] = v;
-
-      CPLFree( data );
-    }
-  }
-
-  return true;
-} // bool QgsRasterLayer::identify
-
 /**
  * @note  The arbitraryness of the returned document is enforced by WMS standards up to at least v1.3.0
  *
@@ -1810,11 +1420,8 @@
     //
     // Get the adjusted matrix stats
     //
-    GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, 1 );
-    QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
+    QString myColorerpretation = mDataProvider->colorInterpretationName ( 1 );
 
-
-
     //
     // Create the legend pixmap - note it is generated on the preadjusted stats
     //
@@ -2066,8 +1673,7 @@
   //
   // Get the adjusted matrix stats
   //
-  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, 1 );
-  QString myColorerpretation = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
+  QString myColorerpretation = mDataProvider->colorInterpretationName ( 1 );
   QPixmap myLegendQPixmap;      //will be initialised once we know what drawing style is active
   QPainter myQPainter;
   //
@@ -2550,9 +2156,12 @@
   {
     QgsDebugMsg( "....found paletted image" );
     QgsColorRampShader myShader;
-    QList<QgsColorRampShader::ColorRampItem> myColorRampItemList = myShader.colorRampItemList();
+    //QList<QgsColorRampShader::ColorRampItem> myColorRampItemList = myShader.colorRampItemList();
 
-    if ( readColorTable( 1, &myColorRampItemList ) )
+    //if ( readColorTable( 1, &myColorRampItemList ) )
+    QList<QgsColorRampShader::ColorRampItem> myColorRampItemList = mDataProvider->colorTable ( 1 );
+    // TODO: add CT capability? It can depends on band (?)
+    if ( myColorRampItemList.size() > 0 )
     {
       QgsDebugMsg( "....got color ramp item list" );
       myShader.setColorRampItemList( myColorRampItemList );
@@ -2602,54 +2211,10 @@
  */
 void QgsRasterLayer::populateHistogram( int theBandNo, int theBinCount, bool theIgnoreOutOfRangeFlag, bool theHistogramEstimatedFlag )
 {
-
-  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
-  QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
-  //calculate the histogram for this band
-  //we assume that it only needs to be calculated if the length of the histogram
-  //vector is not equal to the number of bins
-  //i.e if the histogram has never previously been generated or the user has
-  //selected a new number of bins.
-  if ( myRasterBandStats.histogramVector->size() != theBinCount ||
-       theIgnoreOutOfRangeFlag != myRasterBandStats.isHistogramOutOfRange ||
-       theHistogramEstimatedFlag != myRasterBandStats.isHistogramEstimated )
-  {
-    myRasterBandStats.histogramVector->clear();
-    myRasterBandStats.isHistogramEstimated = theHistogramEstimatedFlag;
-    myRasterBandStats.isHistogramOutOfRange = theIgnoreOutOfRangeFlag;
-    int *myHistogramArray = new int[theBinCount];
-
-
-    /*
-     *  CPLErr GDALRasterBand::GetHistogram (
-     *          double       dfMin,
-     *          double      dfMax,
-     *          int     nBuckets,
-     *          int *   panHistogram,
-     *          int     bIncludeOutOfRange,
-     *          int     bApproxOK,
-     *          GDALProgressFunc    pfnProgress,
-     *          void *      pProgressData
-     *          )
-     */
-    double myerval = ( myRasterBandStats.maximumValue - myRasterBandStats.minimumValue ) / theBinCount;
-    GDALGetRasterHistogram( myGdalBand, myRasterBandStats.minimumValue - 0.1*myerval,
-                            myRasterBandStats.maximumValue + 0.1*myerval, theBinCount, myHistogramArray,
-                            theIgnoreOutOfRangeFlag, theHistogramEstimatedFlag, progressCallback,
-                            this ); //this is the arg for our custome gdal progress callback
-
-    for ( int myBin = 0; myBin < theBinCount; myBin++ )
-    {
-      myRasterBandStats.histogramVector->push_back( myHistogramArray[myBin] );
-      QgsDebugMsg( "Added " + QString::number( myHistogramArray[myBin] ) + " to histogram vector" );
-    }
-
-  }
-  QgsDebugMsg( ">>>>> Histogram vector now contains " + QString::number( myRasterBandStats.histogramVector->size() ) +
-               " elements" );
+  QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo ); 
+  mDataProvider->populateHistogram( theBandNo, myRasterBandStats, theBinCount, theIgnoreOutOfRangeFlag, theHistogramEstimatedFlag );
 }
 
-
 QString QgsRasterLayer::providerKey()
 {
   if ( mProviderKey.isEmpty() )
@@ -2676,105 +2241,14 @@
   return fabs( mGeoTransform[1] );
 }
 
-/**
- * @param theBandNumber the number of the band for which you want a color table
- * @param theList a pointer the object that will hold the color table
- * @return true of a color table was able to be read, false otherwise
- */
-bool QgsRasterLayer::readColorTable( int theBandNumber, QList<QgsColorRampShader::ColorRampItem>* theList )
-{
-  QgsDebugMsg( "entered." );
-  //Invalid band number, segfault prevention
-  if ( 0 >= theBandNumber || 0 == theList )
-  {
-    QgsDebugMsg( "Invalid parameter" );
-    return false;
-  }
 
-  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNumber );
-  GDALColorTableH myGdalColorTable = GDALGetRasterColorTable( myGdalBand );
-
-  if ( myGdalColorTable )
-  {
-    QgsDebugMsg( "Color table found" );
-    int myEntryCount = GDALGetColorEntryCount( myGdalColorTable );
-    GDALColorInterp myColorInterpretation =  GDALGetRasterColorInterpretation( myGdalBand );
-    QgsDebugMsg( "Color Interpretation: " + QString::number(( int )myColorInterpretation ) );
-    GDALPaletteInterp myPaletteInterpretation  = GDALGetPaletteInterpretation( myGdalColorTable );
-    QgsDebugMsg( "Palette Interpretation: " + QString::number(( int )myPaletteInterpretation ) );
-
-    const GDALColorEntry* myColorEntry = 0;
-    for ( int myIterator = 0; myIterator < myEntryCount; myIterator++ )
-    {
-      myColorEntry = GDALGetColorEntry( myGdalColorTable, myIterator );
-
-      if ( !myColorEntry )
-      {
-        continue;
-      }
-      else
-      {
-        //Branch on the color interpretation type
-        if ( myColorInterpretation == GCI_GrayIndex )
-        {
-          QgsColorRampShader::ColorRampItem myColorRampItem;
-          myColorRampItem.label = "";
-          myColorRampItem.value = ( double )myIterator;
-          myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 );
-          theList->append( myColorRampItem );
-        }
-        else if ( myColorInterpretation == GCI_PaletteIndex )
-        {
-          QgsColorRampShader::ColorRampItem myColorRampItem;
-          myColorRampItem.label = "";
-          myColorRampItem.value = ( double )myIterator;
-          //Branch on palette interpretation
-          if ( myPaletteInterpretation  == GPI_RGB )
-          {
-            myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 );
-          }
-          else if ( myPaletteInterpretation  == GPI_CMYK )
-          {
-            myColorRampItem.color = QColor::fromCmyk( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 );
-          }
-          else if ( myPaletteInterpretation  == GPI_HLS )
-          {
-            myColorRampItem.color = QColor::fromHsv( myColorEntry->c1, myColorEntry->c3, myColorEntry->c2, myColorEntry->c4 );
-          }
-          else
-          {
-            myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 );
-          }
-          theList->append( myColorRampItem );
-        }
-        else
-        {
-          QgsDebugMsg( "Color interpretation type not supported yet" );
-          return false;
-        }
-      }
-    }
-  }
-  else
-  {
-    QgsDebugMsg( "No color table found for band " + QString::number( theBandNumber ) );
-    return false;
-  }
-
-  QgsDebugMsg( "Color table loaded sucessfully" );
-  return true;
-}
-
 void QgsRasterLayer::resetNoDataValue()
 {
   mNoDataValue = std::numeric_limits<int>::max();
   mValidNoDataValue = false;
-  //if ( mGdalDataset != NULL && GDALGetRasterCount( mGdalDataset ) > 0 )
   if ( mDataProvider != NULL && mDataProvider->bandCount() > 0 )
   {
     int myRequestValid;
-    //double myValue = GDALGetRasterNoDataValue(
-    //                   GDALGetRasterBand( mGdalDataset, 1 ), &myRequestValid );
 
     // TODO: add 'has null value' to capabilities
     myRequestValid = 1;
@@ -2833,9 +2307,6 @@
   mNoDataValue = -9999.0;
   mValidNoDataValue = false;
 
-  mGdalBaseDataset = 0;
-  mGdalDataset = 0;
-
   //Initialize the last view port structure, should really be a class
   mLastViewPort.rectXOffset = 0;
   mLastViewPort.rectXOffsetFloat = 0.0;
@@ -2851,16 +2322,13 @@
   mLastViewPort.drawableAreaYDim = 0;
 }
 
-// This code should be shared also by vector layer -> move it to QgsMapLayer
-QgsRasterDataProvider* QgsRasterLayer::loadProvider( QString theProviderKey, QString theDataSource ) 
+QLibrary* QgsRasterLayer::loadProviderLibrary( QString theProviderKey ) 
 {
-    QgsDebugMsg( "Entered" );
+  QgsDebugMsg( "Entered" );
   // load the plugin
   QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
   QString ogrlib = pReg->library( theProviderKey );
 
-  //QString ogrlib = libDir + "/libpostgresprovider.so";
-
 #ifdef TESTPROVIDERLIB
   const char *cOgrLib = ( const char * ) ogrlib;
   // test code to help debug provider loading problems
@@ -2887,9 +2355,24 @@
   if ( !loaded )
   {
     QgsLogger::warning( "QgsRasterLayer::setDataProvider: Failed to load " );
-
+    return NULL;
   }
   QgsDebugMsg( "Loaded data provider library" );
+  return myLib;
+}
+
+// This code should be shared also by vector layer -> move it to QgsMapLayer
+QgsRasterDataProvider* QgsRasterLayer::loadProvider( QString theProviderKey, QString theDataSource ) 
+{
+  QgsDebugMsg( "Entered" );
+  QLibrary*  myLib = QgsRasterLayer::loadProviderLibrary( theProviderKey );
+  QgsDebugMsg( "Library loaded" );
+  if ( !myLib )
+  {
+    QgsDebugMsg( "myLib is NULL" );
+    return NULL;
+  }
+
   QgsDebugMsg( "Attempting to resolve the classFactory function" );
   classFactoryFunction_t * classFactory = ( classFactoryFunction_t * ) cast_to_fptr( myLib->resolve( "classFactory" ) );
 
@@ -3016,7 +2499,7 @@
   for ( int i = 1; i <= mBandCount; i++ )
   {
     QgsRasterBandStats myRasterBandStats;
-    myRasterBandStats.bandName = generateBandName( i );
+    myRasterBandStats.bandName = mDataProvider->generateBandName( i );
     myRasterBandStats.bandNumber = i;
     myRasterBandStats.statsGathered = false;
     myRasterBandStats.histogramVector = new QgsRasterBandStats::HistogramVector();
@@ -3466,40 +2949,10 @@
   emit statusChanged( theMessage );
 }
 
-QStringList QgsRasterLayer::subLayers( GDALDatasetH dataset )
-{
-  QStringList subLayers;
 
-  char **metadata = GDALGetMetadata( dataset, "SUBDATASETS" );
-  if ( metadata )
-  {
-    for ( int i = 0; metadata[i] != NULL; i++ )
-    {
-      QString layer = QString::fromUtf8( metadata[i] );
-
-      int pos = layer.indexOf( "_NAME=" );
-      if ( pos >= 0 )
-      {
-        subLayers << layer.mid( pos + 6 );
-      }
-    }
-  }
-
-  QgsDebugMsg( "sublayers:\n  " + subLayers.join( "\n  " ) );
-
-  return subLayers;
-}
-
 QStringList QgsRasterLayer::subLayers() const
 {
-  if ( mDataProvider )
-  {
-    return mDataProvider->subLayers();
-  }
-  else
-  {
-    return subLayers( mGdalDataset );
-  }
+  return mDataProvider->subLayers();
 }
 
 void QgsRasterLayer::thumbnailAsPixmap( QPixmap * theQPixmap )
@@ -4280,14 +3733,10 @@
     return;
   }
 
-  GDALRasterBandH myGdalRedBand = GDALGetRasterBand( mGdalDataset, myRedBandNo );
-  GDALRasterBandH myGdalGreenBand = GDALGetRasterBand( mGdalDataset, myGreenBandNo );
-  GDALRasterBandH myGdalBlueBand = GDALGetRasterBand( mGdalDataset, myBlueBandNo );
+  int myRedType = mDataProvider->dataType( myRedBandNo );
+  int myGreenType = mDataProvider->dataType( myGreenBandNo );
+  int myBlueType = mDataProvider->dataType( myBlueBandNo );
 
-  GDALDataType myRedType = GDALGetRasterDataType( myGdalRedBand );
-  GDALDataType myGreenType = GDALGetRasterDataType( myGdalGreenBand );
-  GDALDataType myBlueType = GDALGetRasterDataType( myGdalBlueBand );
-
   QRgb* redImageScanLine = 0;
   void* redRasterScanLine = 0;
   QRgb* greenImageScanLine = 0;
@@ -4323,20 +3772,16 @@
   {
     //This case will be true the first time the image is loaded, so just approimate the min max to keep
     //from calling generate raster band stats
-    double GDALrange[2];
     mRGBMinimumMaximumEstimated = true;
 
-    GDALComputeRasterMinMax( myGdalRedBand, 1, GDALrange ); //Approximate
-    setMaximumValue( myRedBandNo, GDALrange[1] );
-    setMinimumValue( myRedBandNo, GDALrange[0] );
+    setMinimumValue( myRedBandNo, mDataProvider->minimumValue ( myRedBandNo ) );
+    setMaximumValue( myRedBandNo, mDataProvider->maximumValue ( myRedBandNo ) );
 
-    GDALComputeRasterMinMax( myGdalGreenBand, 1, GDALrange ); //Approximate
-    setMaximumValue( myGreenBandNo, GDALrange[1] );
-    setMinimumValue( myGreenBandNo, GDALrange[0] );
+    setMinimumValue( myGreenBandNo, mDataProvider->minimumValue ( myGreenBandNo ) );
+    setMaximumValue( myGreenBandNo, mDataProvider->maximumValue ( myGreenBandNo ) );
 
-    GDALComputeRasterMinMax( myGdalBlueBand, 1, GDALrange ); //Approximate
-    setMaximumValue( myBlueBandNo, GDALrange[1] );
-    setMinimumValue( myBlueBandNo, GDALrange[0] );
+    setMinimumValue( myBlueBandNo, mDataProvider->minimumValue ( myBlueBandNo ) );
+    setMaximumValue( myBlueBandNo, mDataProvider->maximumValue ( myBlueBandNo ) );
   }
 
   //Read and display pixels
@@ -4352,14 +3797,11 @@
   QgsContrastEnhancement* myGreenContrastEnhancement = contrastEnhancement( myGreenBandNo );
   QgsContrastEnhancement* myBlueContrastEnhancement = contrastEnhancement( myBlueBandNo );
 
-  //QgsRasterImageBuffer redImageBuffer( myGdalRedBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer redImageBuffer( mDataProvider, myRedBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   redImageBuffer.reset();
-  //QgsRasterImageBuffer greenImageBuffer( myGdalGreenBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer greenImageBuffer( mDataProvider, myGreenBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   greenImageBuffer.setWritingEnabled( false ); //only draw to redImageBuffer
   greenImageBuffer.reset();
-  //QgsRasterImageBuffer blueImageBuffer( myGdalBlueBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer blueImageBuffer( mDataProvider, myBlueBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   blueImageBuffer.setWritingEnabled( false ); //only draw to redImageBuffer
   blueImageBuffer.reset();
@@ -4454,11 +3896,8 @@
     return;
   }
 
-  //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
-  //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
   int myDataType = mDataProvider->dataType( theBandNo );
 
-  //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   imageBuffer.reset();
 
@@ -4537,11 +3976,8 @@
     return;
   }
 
-  //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
-  //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
   int myDataType = mDataProvider->dataType( theBandNo );
 
-  //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   imageBuffer.reset();
 
@@ -4620,11 +4056,8 @@
   }
 
   QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
-  //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
-  //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
   int myDataType = mDataProvider->dataType( theBandNo );
 
-  //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   imageBuffer.reset();
 
@@ -4702,7 +4135,7 @@
  * @param theQPainter pointer to the QPainter onto which the layer should be drawn.
  * @param theRasterViewPort pointer to the ViewPort struct containing dimensions of viewable area and subset area to be extracted from data file.
  * @param theQgsMapToPixel transformation coordinate to map canvas pixel
- * @param theBandNo pointer to the GDALRasterBand which should be rendered.
+ * @param theBandNo the number of the band which should be rendered.
  * @note not supported at this time
  */
 void QgsRasterLayer::drawPalettedMultiBandColor( QPainter * theQPainter, QgsRasterViewPort * theRasterViewPort,
@@ -4720,11 +4153,8 @@
     return;
   }
 
-  //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
-  //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
   int myDataType = mDataProvider->dataType( theBandNo );
   QgsDebugMsg( "myDataType = " + QString::number( myDataType) ); 
-  //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   imageBuffer.reset();
 
@@ -4816,11 +4246,8 @@
   }
 
   QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
-  //GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
-  //GDALDataType myDataType = GDALGetRasterDataType( myGdalBand );
   int myDataType = mDataProvider->dataType( theBandNo );
 
-  //QgsRasterImageBuffer imageBuffer( myGdalBand, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   QgsRasterImageBuffer imageBuffer( mDataProvider, theBandNo, theQPainter, theRasterViewPort, theQgsMapToPixel, &mGeoTransform[0] );
   imageBuffer.reset();
 
@@ -4891,35 +4318,17 @@
       {
         //Normal
         imageScanLine[ i ] = qRgba( myRedValue, myGreenValue, myBlueValue, myAlphaValue );
-        QgsDebugMsg ( QString ( "%1 value :  %2 rgba : %3 %4 %5 %6" ).arg (i).arg( myPixelValue ).arg(myRedValue).arg(myGreenValue).arg(myBlueValue).arg(myAlphaValue) );
+        //QgsDebugMsg ( QString ( "%1 value :  %2 rgba : %3 %4 %5 %6" ).arg (i).arg( myPixelValue ).arg(myRedValue).arg(myGreenValue).arg(myBlueValue).arg(myAlphaValue) );
       }
     }
   }
 }
 
+//QString QgsRasterLayer::generateBandName( int theBandNumber )
+//{
+  //return tr( "Band" ) + QString( " %1" ) .arg( theBandNumber,  1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) );
+//}
 
-void QgsRasterLayer::closeDataset()
-{
-  if ( !mValid ) return;
-  mValid = false;
-
-  GDALDereferenceDataset( mGdalBaseDataset );
-  mGdalBaseDataset = NULL;
-
-  GDALClose( mGdalDataset );
-  mGdalDataset = NULL;
-
-  mHasPyramids = false;
-  mPyramidList.clear();
-
-  mRasterStatsList.clear();
-}
-
-QString QgsRasterLayer::generateBandName( int theBandNumber )
-{
-  return tr( "Band" ) + QString( " %1" ) .arg( theBandNumber,  1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) );
-}
-
 /**
  * This method looks to see if a given band name exists.
  *@note This function is no longer really needed and about to be removed
@@ -4929,10 +4338,9 @@
   //TODO: This function is no longer really needed and about be removed -- it is only used to see if "Palette" exists which is not the correct way to see if a band is paletted or not
   QgsDebugMsg( "Looking for band : " + theBandName );
 
-  for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
+  for ( int i = 1; i <= mDataProvider->bandCount(); i++ )
   {
-    GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, i );
-    QString myColorQString = GDALGetColorInterpretationName( GDALGetRasterColorInterpretation( myGdalBand ) );
+    QString myColorQString = mDataProvider->colorInterpretationName ( i );
 #ifdef QGISDEBUG
     QgsLogger::debug( "band", i, __FILE__, __FUNCTION__, __LINE__, 2 );
 #endif
@@ -5081,7 +4489,7 @@
     }
 
   }
-  // INSTANCE: > 2x2, so just use the image filled by GDAL
+  // INSTANCE: > 2x2, so just use the image filled by provider
   else
   {
     theQPainter->drawImage( static_cast<int>( theRasterViewPort->topLeftPoint.x() + 0.5 ),
@@ -5102,11 +4510,8 @@
  *data type is the same as raster band. The memory must be released later!
  *  \return pointer to the memory
  */
-//void *QgsRasterLayer::readData( GDALRasterBandH gdalBand, QgsRasterViewPort *viewPort )
 void *QgsRasterLayer::readData( int bandNo, QgsRasterViewPort *viewPort )
 {
- // GDALDataType type = GDALGetRasterDataType( gdalBand );
-  //int size = GDALGetDataTypeSize( type ) / 8;
   int size = mDataProvider->dataTypeSize(bandNo)/8;
 
   QgsDebugMsg( "calling RasterIO with " +
@@ -5140,6 +4545,14 @@
     //{
       //QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
     //}
+    // TODO: check extent
+    QgsRectangle partExtent ( 
+      viewPort->mDrawnExtent.xMinimum(), 
+      viewPort->mDrawnExtent.yMinimum(),
+      viewPort->mDrawnExtent.xMaximum(), 
+      viewPort->mDrawnExtent.yMaximum() 
+    );
+    mDataProvider->readBlock ( bandNo, partExtent, viewPort->drawableAreaXDim, viewPort->drawableAreaYDim, data );
   }
   return data;
 }
@@ -5200,12 +4613,13 @@
 
   if ( mLastModified < QgsRasterLayer::lastModified( source() ) )
   {
-    if ( !usesProvider() )
-    {
-      QgsDebugMsg( "Outdated -> reload" );
-      closeDataset();
-      return readFile( source() );
-    }
+    // TODO: lastModified to provider -> outdated
+    // TODO: check what has to be cleard, rebuild
+    mHasPyramids = false;
+    mPyramidList.clear();
+
+    mRasterStatsList.clear();
+    mValid = mDataProvider->reload();
   }
   return true;
 }
@@ -5247,7 +4661,7 @@
     int myBandNumber = myBandNameComponents.at( 1 ).toInt();
     if ( myBandNumber > 0 )
     {
-      QString myBandName = generateBandName( myBandNumber );
+      QString myBandName = mDataProvider->generateBandName( myBandNumber );
       for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
       {
         //find out the name of this band
@@ -5486,8 +4900,6 @@
   //                             mViewPort->rectYOffset + mCurrentRow, mViewPort->clippedWidth, rasterYSize,
   //                             mCurrentGDALData, xSize, ySize, type, 0, 0 );
 
-
-  // TODO !!! get correct extent
   double yMax = mViewPort->mDrawnExtent.yMaximum() - mCurrentRow * mMapToPixel->mapUnitsPerPixel();
   double yMin = yMax - ySize * mMapToPixel->mapUnitsPerPixel();
 
@@ -5647,3 +5059,16 @@
     GDALAllRegister();
 }
 
+// Keep this for QgsRasterLayerProperties
+bool QgsRasterLayer::readColorTable( int theBandNumber, QList<QgsColorRampShader::ColorRampItem>* theList )
+{
+  // TODO : check if exists - returned vale?
+    //if ( readColorTable( 1, &myColorRampItemList ) )
+  QList<QgsColorRampShader::ColorRampItem> myColorRampItemList = mDataProvider->colorTable ( theBandNumber );
+  if ( myColorRampItemList.size() == 0 ) {
+    return false;
+  }
+  *theList = myColorRampItemList;
+  return true;
+}
+

Modified: branches/raster-providers/src/core/raster/qgsrasterlayer.h
===================================================================
--- branches/raster-providers/src/core/raster/qgsrasterlayer.h	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/core/raster/qgsrasterlayer.h	2010-11-14 18:14:56 UTC (rev 14650)
@@ -286,7 +286,7 @@
      */
     static bool isValidRasterFileName( const QString & theFileNameQString, QString &retError );
     static bool isValidRasterFileName( const QString & theFileNameQString );
-    static QStringList subLayers( GDALDatasetH dataset );
+    //static QStringList subLayers( GDALDatasetH dataset );
 
 
     /** Return time stamp for given file name */
@@ -317,6 +317,7 @@
                           const QString & crs,
                           bool loadDefaultStyleFlag );
 
+    static QLibrary* loadProviderLibrary( QString theProviderKey);
     static QgsRasterDataProvider* loadProvider( QString theProviderKey, QString theDataSource = 0);
     
 
@@ -562,6 +563,7 @@
     double rasterUnitsPerPixel();
 
     /** \brief Read color table from GDAL raster band */
+    // Keep this for QgsRasterLayerProperties
     bool readColorTable( int theBandNumber, QList<QgsColorRampShader::ColorRampItem>* theList );
 
     /** \brief Simple reset function that set the noDataValue back to the value stored in the first raster band */
@@ -667,6 +669,7 @@
                            bool theTryInternalFlag = false );
 
     /** \brief Populate the histogram vector for a given band */
+    
     void populateHistogram( int theBandNoInt,
                             int theBinCountInt = 256,
                             bool theIgnoreOutOfRangeFlag = true,
@@ -840,10 +843,10 @@
     QString mErrorCaption;
 
     /** \brief Pointer to the gdaldataset */
-    GDALDatasetH mGdalBaseDataset;
+    //GDALDatasetH mGdalBaseDataset;
 
     /** \brief Pointer to the gdaldataset (possibly warped vrt) */
-    GDALDatasetH mGdalDataset;
+    //GDALDatasetH mGdalDataset;
 
     /** \brief Values for mapping pixel to world coordinates. Contents of this array are the same as the GDAL adfGeoTransform */
     double mGeoTransform[6];

Modified: branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp
===================================================================
--- branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/providers/gdal/qgsgdalprovider.cpp	2010-11-14 18:14:56 UTC (rev 14650)
@@ -28,6 +28,8 @@
 #include "qgscoordinatetransform.h"
 #include "qgsrectangle.h"
 #include "qgscoordinatereferencesystem.h"
+#include "qgsrasterbandstats.h"
+#include "qgsrasterpyramid.h"
 
 #include <QImage>
 #include <QSettings>
@@ -206,6 +208,51 @@
   }
   QgsDebugMsg( QString("mNoDataValue = %1").arg ( mNoDataValue ) ); 
 
+  // This block of code was in old version in QgsRasterLayer::bandStatistics 
+  //ifdefs below to remove compiler warning about unused vars
+#ifdef QGISDEBUG
+/*
+  int success;
+  double GDALminimum = GDALGetRasterMinimum( myGdalBand, &success );
+
+  if ( ! success )
+  {
+    QgsDebugMsg( "myGdalBand->GetMinimum() failed" );
+  }
+
+  double GDALmaximum = GDALGetRasterMaximum( myGdalBand, &success );
+
+  if ( ! success )
+  {
+    QgsDebugMsg( "myGdalBand->GetMaximum() failed" );
+  }
+
+  double GDALnodata = GDALGetRasterNoDataValue( myGdalBand, &success );
+
+  if ( ! success )
+  {
+    QgsDebugMsg( "myGdalBand->GetNoDataValue() failed" );
+  }
+
+  QgsLogger::debug( "GDALminium: ", GDALminimum, __FILE__, __FUNCTION__, __LINE__ );
+  QgsLogger::debug( "GDALmaximum: ", GDALmaximum, __FILE__, __FUNCTION__, __LINE__ );
+  QgsLogger::debug( "GDALnodata: ", GDALnodata, __FILE__, __FUNCTION__, __LINE__ );
+
+  double GDALrange[2];          // calculated min/max, as opposed to the
+  // dataset provided
+
+  GDALComputeRasterMinMax( myGdalBand, 1, GDALrange );
+  QgsLogger::debug( "approximate computed GDALminium:", GDALrange[0], __FILE__, __FUNCTION__, __LINE__, 1 );
+  QgsLogger::debug( "approximate computed GDALmaximum:", GDALrange[1], __FILE__, __FUNCTION__, __LINE__, 1 );
+
+  GDALComputeRasterMinMax( myGdalBand, 0, GDALrange );
+  QgsLogger::debug( "exactly computed GDALminium:", GDALrange[0] );
+  QgsLogger::debug( "exactly computed GDALmaximum:", GDALrange[1] );
+
+  QgsDebugMsg( "starting manual stat computation" );
+*/
+#endif
+
   mValid = true;
   QgsDebugMsg( "end" );
 }
@@ -224,6 +271,25 @@
 }
 
 
+// This was used by raster layer to reload data
+void QgsGdalProvider::closeDataset()
+{
+  if ( !mValid ) return;
+  mValid = false;
+
+  GDALDereferenceDataset( mGdalBaseDataset );
+  mGdalBaseDataset = NULL;
+
+  GDALClose( mGdalDataset );
+  mGdalDataset = NULL;
+
+  //mHasPyramids = false;
+  //mPyramidList.clear();
+
+  //mRasterStatsList.clear();
+}
+
+
     
 QString QgsGdalProvider::metadata()
 {
@@ -504,21 +570,96 @@
   return  mMaximum[theBandNo-1];
 }
 
-QList<QgsColorRampShader::ColorRampItem> QgsGdalProvider::colorTable(int bandNo)const {
-  // TODO
+/**
+ * @param theBandNumber the number of the band for which you want a color table
+ * @param theList a pointer the object that will hold the color table
+ * @return true of a color table was able to be read, false otherwise
+ */
+//bool QgsRasterLayer::readColorTable( int theBandNumber, QList<QgsColorRampShader::ColorRampItem>* theList )
+QList<QgsColorRampShader::ColorRampItem> QgsGdalProvider::colorTable(int theBandNumber)const 
+{
+  QgsDebugMsg( "entered." );
   QList<QgsColorRampShader::ColorRampItem> ct;
   
-  //double v, r, g, b;
-  //for (i = colors.begin(); i != colors.end(); ++i)
-  //{
-    //QgsColorRampShader::ColorRampItem ctItem2;
-    //ctItem2.value = i->value2;
-    //ctItem2.color = QColor::fromRgb( i->red2, i->green2, i->blue2);
-    //ct.append(ctItem2);
-    //QgsDebugMsg( QString("color %1 %2 %3 %4").arg(i->value2).arg(i->red2).arg(i->green2).arg(i->blue2) );
 
-    //v = i->value2; r = i->red2; g = i->green2; b = i->blue2;
-  //}
+  //Invalid band number, segfault prevention
+  if ( 0 >= theBandNumber )
+  {
+    QgsDebugMsg( "Invalid parameter" );
+    return ct;
+  }
+
+  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNumber );
+  GDALColorTableH myGdalColorTable = GDALGetRasterColorTable( myGdalBand );
+
+  if ( myGdalColorTable )
+  {
+    QgsDebugMsg( "Color table found" );
+    int myEntryCount = GDALGetColorEntryCount( myGdalColorTable );
+    GDALColorInterp myColorInterpretation =  GDALGetRasterColorInterpretation( myGdalBand );
+    QgsDebugMsg( "Color Interpretation: " + QString::number(( int )myColorInterpretation ) );
+    GDALPaletteInterp myPaletteInterpretation  = GDALGetPaletteInterpretation( myGdalColorTable );
+    QgsDebugMsg( "Palette Interpretation: " + QString::number(( int )myPaletteInterpretation ) );
+
+    const GDALColorEntry* myColorEntry = 0;
+    for ( int myIterator = 0; myIterator < myEntryCount; myIterator++ )
+    {
+      myColorEntry = GDALGetColorEntry( myGdalColorTable, myIterator );
+
+      if ( !myColorEntry )
+      {
+        continue;
+      }
+      else
+      {
+        //Branch on the color interpretation type
+        if ( myColorInterpretation == GCI_GrayIndex )
+        {
+          QgsColorRampShader::ColorRampItem myColorRampItem;
+          myColorRampItem.label = "";
+          myColorRampItem.value = ( double )myIterator;
+          myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 );
+          ct.append( myColorRampItem );
+        }
+        else if ( myColorInterpretation == GCI_PaletteIndex )
+        {
+          QgsColorRampShader::ColorRampItem myColorRampItem;
+          myColorRampItem.label = "";
+          myColorRampItem.value = ( double )myIterator;
+          //Branch on palette interpretation
+          if ( myPaletteInterpretation  == GPI_RGB )
+          {
+            myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 );
+          }
+          else if ( myPaletteInterpretation  == GPI_CMYK )
+          {
+            myColorRampItem.color = QColor::fromCmyk( myColorEntry->c1, myColorEntry->c2, myColorEntry->c3, myColorEntry->c4 );
+          }
+          else if ( myPaletteInterpretation  == GPI_HLS )
+          {
+            myColorRampItem.color = QColor::fromHsv( myColorEntry->c1, myColorEntry->c3, myColorEntry->c2, myColorEntry->c4 );
+          }
+          else
+          {
+            myColorRampItem.color = QColor::fromRgb( myColorEntry->c1, myColorEntry->c1, myColorEntry->c1, myColorEntry->c4 );
+          }
+          ct.append( myColorRampItem );
+        }
+        else
+        {
+          QgsDebugMsg( "Color interpretation type not supported yet" );
+          return ct;
+        }
+      }
+    }
+  }
+  else
+  {
+    QgsDebugMsg( "No color table found for band " + QString::number( theBandNumber ) );
+    return ct;
+  }
+
+  QgsDebugMsg( "Color table loaded sucessfully" );
   return ct;
 }
 
@@ -550,10 +691,67 @@
 bool QgsGdalProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
 {
   QgsDebugMsg( "Entered" );
-  // TODO
-  theResults["Error"] = tr( "Not implemented" );
-  //theResults["Error"] = tr( "Out of extent" );
-  //theResults = QgsGdal::query( mGisdbase, mLocation, mMapset, mMapName, QgsGdal::Raster, thePoint.x(), thePoint.y() );
+  if ( !mExtent.contains( thePoint ) )
+  {
+    // Outside the raster
+    for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
+    {
+      theResults[ generateBandName( i )] = tr( "out of extent" );
+    }
+  }
+  else
+  {
+    double x = thePoint.x();
+    double y = thePoint.y();
+
+    /* Calculate the row / column where the point falls */
+    double xres = ( mExtent.xMaximum() - mExtent.xMinimum() ) / mWidth;
+    double yres = ( mExtent.yMaximum() - mExtent.yMinimum() ) / mHeight;
+
+    // Offset, not the cell index -> flor
+    int col = ( int ) floor(( x - mExtent.xMinimum() ) / xres );
+    int row = ( int ) floor(( mExtent.yMaximum() - y ) / yres );
+
+    QgsDebugMsg( "row = " + QString::number( row ) + " col = " + QString::number( col ) );
+
+    for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
+    {
+      GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, i );
+      //GDALDataType type = GDALGetRasterDataType( gdalBand );
+      //int size = GDALGetDataTypeSize( type ) / 8;
+
+      //void *data = CPLMalloc( size );
+      double value;
+
+      CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, 1, 1,
+          &value, 1, 1, GDT_Float64, 0, 0 );
+
+      if ( err != CPLE_None )
+      {
+        QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
+      }
+
+      //double value = readValue( data, type, 0 );
+#ifdef QGISDEBUG
+      QgsLogger::debug( "value", value, 1, __FILE__, __FUNCTION__, __LINE__ );
+#endif
+      QString v;
+
+      if ( mValidNoDataValue && ( fabs( value - mNoDataValue ) <= TINY_VALUE || value != value ) )
+      {
+        v = tr( "null (no data)" );
+      }
+      else
+      {
+        v.setNum( value );
+      }
+
+      theResults[ generateBandName( i )] = v;
+
+      //CPLFree( data );
+    }
+  }
+
   return true;
 }
 
@@ -616,9 +814,9 @@
   return GDALGetRasterCount( mGdalDataset);
 }
 
-int QgsGdalProvider::colorInterpretation ( int bandNo ) const {
-  // TODO
-  return QgsRasterDataProvider::GrayIndex;
+int QgsGdalProvider::colorInterpretation ( int theBandNo ) const {
+  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo ); 
+  return GDALGetRasterColorInterpretation( myGdalBand );
 }
 
 void QgsGdalProvider::registerGdalDrivers()
@@ -663,7 +861,372 @@
 {
   return PROVIDER_DESCRIPTION;
 }
+
+//QStringList QgsGdalProvider::subLayers( GDALDatasetH dataset )
+// This is used also by global isValidRasterFileName
+QStringList subLayers( GDALDatasetH dataset )
+{
+  QStringList subLayers;
+
+  char **metadata = GDALGetMetadata( dataset, "SUBDATASETS" );
+  if ( metadata )
+  {
+    for ( int i = 0; metadata[i] != NULL; i++ )
+    {
+      QString layer = QString::fromUtf8( metadata[i] );
+
+      int pos = layer.indexOf( "_NAME=" );
+      if ( pos >= 0 )
+      {
+        subLayers << layer.mid( pos + 6 );
+      }
+    }
+  }
+
+  QgsDebugMsg( "sublayers:\n  " + subLayers.join( "\n  " ) );
+
+  return subLayers;
+}
+
+void QgsGdalProvider::populateHistogram( int theBandNo,   QgsRasterBandStats & theBandStats, int theBinCount, bool theIgnoreOutOfRangeFlag, bool theHistogramEstimatedFlag )
+{
+  GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
+  //QgsRasterBandStats myRasterBandStats = bandStatistics( theBandNo );
+  //calculate the histogram for this band
+  //we assume that it only needs to be calculated if the length of the histogram
+  //vector is not equal to the number of bins
+  //i.e if the histogram has never previously been generated or the user has
+  //selected a new number of bins.
+  if ( theBandStats.histogramVector->size() != theBinCount ||
+       theIgnoreOutOfRangeFlag != theBandStats.isHistogramOutOfRange ||
+       theHistogramEstimatedFlag != theBandStats.isHistogramEstimated )
+  {
+    theBandStats.histogramVector->clear();
+    theBandStats.isHistogramEstimated = theHistogramEstimatedFlag;
+    theBandStats.isHistogramOutOfRange = theIgnoreOutOfRangeFlag;
+    int *myHistogramArray = new int[theBinCount];
+
+
+    /*
+     *  CPLErr GDALRasterBand::GetHistogram (
+     *          double       dfMin,
+     *          double      dfMax,
+     *          int     nBuckets,
+     *          int *   panHistogram,
+     *          int     bIncludeOutOfRange,
+     *          int     bApproxOK,
+     *          GDALProgressFunc    pfnProgress,
+     *          void *      pProgressData
+     *          )
+     */
+    double myerval = ( theBandStats.maximumValue - theBandStats.minimumValue ) / theBinCount;
+    GDALGetRasterHistogram( myGdalBand, theBandStats.minimumValue - 0.1*myerval,
+                            theBandStats.maximumValue + 0.1*myerval, theBinCount, myHistogramArray,
+                            theIgnoreOutOfRangeFlag, theHistogramEstimatedFlag, progressCallback,
+                            this ); //this is the arg for our custome gdal progress callback
+
+    for ( int myBin = 0; myBin < theBinCount; myBin++ )
+    {
+      theBandStats.histogramVector->push_back( myHistogramArray[myBin] );
+      QgsDebugMsg( "Added " + QString::number( myHistogramArray[myBin] ) + " to histogram vector" );
+    }
+
+  }
+  QgsDebugMsg( ">>>>> Histogram vector now contains " + QString::number( theBandStats.histogramVector->size() ) +
+               " elements" );
+}
+
+/*
+ * This will speed up performance at the expense of hard drive space.
+ * Also, write access to the file is required for creating internal pyramids,
+ * and to the directory in which the files exists if external
+ * pyramids (.ovr) are to be created. If no parameter is passed in
+ * it will default to nearest neighbor resampling.
+ *
+ * @param theTryInternalFlag - Try to make the pyramids internal if supported (e.g. geotiff). If not supported it will revert to creating external .ovr file anyway.
+ * @return null string on success, otherwise a string specifying error
+ */
+QString QgsGdalProvider::buildPyramids(  QList<QgsRasterPyramid> const & theRasterPyramidList,
+                                       QString const & theResamplingMethod, bool theTryInternalFlag )
+{
+  //TODO: Consider making theRasterPyramidList modifyable by this method to indicate if the pyramid exists after build attempt
+  //without requiring the user to rebuild the pyramid list to get the updated infomation
+
+  //
+  // Note: Make sure the raster is not opened in write mode
+  // in order to force overviews to be written to a separate file.
+  // Otherwise reoopen it in read/write mode to stick overviews
+  // into the same file (if supported)
+  //
+
+
+  // TODO add signal and connect from rasterlayer
+  //emit drawingProgress( 0, 0 );
+  //first test if the file is writeable
+  //QFileInfo myQFile( mDataSource );
+  QFileInfo myQFile( dataSourceUri() );
+
+  if ( !myQFile.isWritable() )
+  {
+    return "ERROR_WRITE_ACCESS";
+  }
+
+  if ( mGdalDataset != mGdalBaseDataset )
+  {
+    QgsLogger::warning( "Pyramid building not currently supported for 'warped virtual dataset'." );
+    return "ERROR_VIRTUAL";
+  }
+
+  if ( theTryInternalFlag )
+  {
+    // libtiff < 4.0 has a bug that prevents safe building of overviews on JPEG compressed files
+    // we detect libtiff < 4.0 by checking that BIGTIFF is not in the creation options of the GTiff driver
+    // see https://trac.osgeo.org/qgis/ticket/1357
+    const char* pszGTiffCreationOptions =
+      GDALGetMetadataItem( GDALGetDriverByName( "GTiff" ), GDAL_DMD_CREATIONOPTIONLIST, "" );
+    if ( strstr( pszGTiffCreationOptions, "BIGTIFF" ) == NULL )
+    {
+      QString myCompressionType = QString( GDALGetMetadataItem( mGdalDataset, "COMPRESSION", "IMAGE_STRUCTURE" ) );
+      if ( "JPEG" == myCompressionType )
+      {
+        return "ERROR_JPEG_COMPRESSION";
+      }
+    }
+
+    //close the gdal dataset and reopen it in read / write mode
+    GDALClose( mGdalDataset );
+    mGdalBaseDataset = GDALOpen( QFile::encodeName( dataSourceUri() ).constData(), GA_Update );
+
+    // if the dataset couldn't be opened in read / write mode, tell the user
+    if ( !mGdalBaseDataset )
+    {
+      //mGdalBaseDataset = GDALOpen( QFile::encodeName( mDataSource ).constData(), GA_ReadOnly );
+      mGdalBaseDataset = GDALOpen( QFile::encodeName( dataSourceUri()).constData(), GA_ReadOnly );
+      //Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
+      mGdalDataset = mGdalBaseDataset;
+      return "ERROR_WRITE_FORMAT";
+    }
+  }
+
+  //
+  // Iterate through the Raster Layer Pyramid Vector, building any pyramid
+  // marked as exists in eaxh RasterPyramid struct.
+  //
+  CPLErr myError; //in case anything fails
+  int myCount = 1;
+  int myTotal = theRasterPyramidList.count();
+  QList<QgsRasterPyramid>::const_iterator myRasterPyramidIterator;
+  for ( myRasterPyramidIterator = theRasterPyramidList.begin();
+        myRasterPyramidIterator != theRasterPyramidList.end();
+        ++myRasterPyramidIterator )
+  {
+#ifdef QGISDEBUG
+    QgsLogger::debug( "Build pyramids:: Level", ( *myRasterPyramidIterator ).level, 1, __FILE__, __FUNCTION__, __LINE__ );
+    QgsLogger::debug( "x", ( *myRasterPyramidIterator ).xDim, 1, __FILE__, __FUNCTION__, __LINE__ );
+    QgsLogger::debug( "y", ( *myRasterPyramidIterator ).yDim, 1, __FILE__, __FUNCTION__, __LINE__ );
+    QgsLogger::debug( "exists :", ( *myRasterPyramidIterator ).exists,  1, __FILE__, __FUNCTION__, __LINE__ );
+#endif
+    if (( *myRasterPyramidIterator ).build )
+    {
+      QgsDebugMsg( "Building....." );
+      //emit drawingProgress( myCount, myTotal );
+      int myOverviewLevelsArray[1] = {( *myRasterPyramidIterator ).level };
+      /* From : http://remotesensing.org/gdal/classGDALDataset.html#a23
+       * pszResampling : one of "NEAREST", "AVERAGE" or "MODE" controlling the downsampling method applied.
+       * nOverviews : number of overviews to build.
+       * panOverviewList : the list of overview decimation factors to build.
+       * nBand : number of bands to build overviews for in panBandList. Build for all bands if this is 0.
+       * panBandList : list of band numbers.
+       * pfnProgress : a function to call to report progress, or NULL.
+       * pProgressData : application data to pass to the progress function.
+       */
+      //build the pyramid and show progress to console
+      try
+      {
+
+        //build the pyramid and show progress to console
+        //NOTE this (magphase) is disabled in the gui since it tends
+        //to create corrupted images. The images can be repaired
+        //by running one of the other resampling strategies below.
+        //see ticket #284
+        if ( theResamplingMethod == tr( "Average Magphase" ) )
+        {
+          myError = GDALBuildOverviews( mGdalBaseDataset, "MODE", 1, myOverviewLevelsArray, 0, NULL,
+                                        progressCallback, this ); //this is the arg for the gdal progress callback
+        }
+        else if ( theResamplingMethod == tr( "Average" ) )
+
+        {
+          myError = GDALBuildOverviews( mGdalBaseDataset, "AVERAGE", 1, myOverviewLevelsArray, 0, NULL,
+                                        progressCallback, this ); //this is the arg for the gdal progress callback
+        }
+        else // fall back to nearest neighbor
+        {
+          myError = GDALBuildOverviews( mGdalBaseDataset, "NEAREST", 1, myOverviewLevelsArray, 0, NULL,
+                                        progressCallback, this ); //this is the arg for the gdal progress callback
+        }
+
+        if ( myError == CE_Failure || CPLGetLastErrorNo() == CPLE_NotSupported )
+        {
+          //something bad happenend
+          //QString myString = QString (CPLGetLastError());
+          GDALClose( mGdalBaseDataset );
+          //mGdalBaseDataset = GDALOpen( QFile::encodeName( mDataSource ).constData(), GA_ReadOnly );
+          mGdalBaseDataset = GDALOpen( QFile::encodeName( dataSourceUri() ).constData(), GA_ReadOnly );
+          //Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
+          mGdalDataset = mGdalBaseDataset;
+
+          //emit drawingProgress( 0, 0 );
+          return "FAILED_NOT_SUPPORTED";
+        }
+        else
+        {
+          //make sure the raster knows it has pyramids
+          mHasPyramids = true;
+        }
+        myCount++;
+
+      }
+      catch ( CPLErr )
+      {
+        QgsLogger::warning( "Pyramid overview building failed!" );
+      }
+    }
+  }
+
+  QgsDebugMsg( "Pyramid overviews built" );
+  if ( theTryInternalFlag )
+  {
+    //close the gdal dataset and reopen it in read only mode
+    GDALClose( mGdalBaseDataset );
+    //mGdalBaseDataset = GDALOpen( QFile::encodeName( mDataSource ).constData(), GA_ReadOnly );
+    mGdalBaseDataset = GDALOpen( QFile::encodeName( dataSourceUri() ).constData(), GA_ReadOnly );
+    //Since we are not a virtual warped dataset, mGdalDataSet and mGdalBaseDataset are supposed to be the same
+    mGdalDataset = mGdalBaseDataset;
+  }
+
+  //emit drawingProgress( 0, 0 );
+  return NULL; // returning null on success
+}
+
+QList<QgsRasterPyramid> QgsGdalProvider::buildPyramidList()
+{
+  //
+  // First we build up a list of potential pyramid layers
+  //
+  int myWidth = mWidth;
+  int myHeight = mHeight;
+  int myDivisor = 2;
+
+  //if ( mDataProvider ) return mPyramidList;
+
+  GDALRasterBandH myGDALBand = GDALGetRasterBand( mGdalDataset, 1 ); //just use the first band
+
+  mPyramidList.clear();
+  QgsDebugMsg( "Building initial pyramid list" );
+  while (( myWidth / myDivisor > 32 ) && (( myHeight / myDivisor ) > 32 ) )
+  {
+
+    QgsRasterPyramid myRasterPyramid;
+    myRasterPyramid.level = myDivisor;
+    myRasterPyramid.xDim = ( int )( 0.5 + ( myWidth / ( double )myDivisor ) );
+    myRasterPyramid.yDim = ( int )( 0.5 + ( myHeight / ( double )myDivisor ) );
+    myRasterPyramid.exists = false;
+#ifdef QGISDEBUG
+    QgsLogger::debug( "Pyramid", myRasterPyramid.level, 1, __FILE__, __FUNCTION__, __LINE__ );
+    QgsLogger::debug( "xDim", myRasterPyramid.xDim, 1, __FILE__, __FUNCTION__, __LINE__ );
+    QgsLogger::debug( "yDim", myRasterPyramid.yDim, 1, __FILE__, __FUNCTION__, __LINE__ );
+#endif
+
+    //
+    // Now we check if it actually exists in the raster layer
+    // and also adjust the dimensions if the dimensions calculated
+    // above are only a near match.
+    //
+    const int myNearMatchLimit = 5;
+    if ( GDALGetOverviewCount( myGDALBand ) > 0 )
+    {
+      int myOverviewCount;
+      for ( myOverviewCount = 0;
+            myOverviewCount < GDALGetOverviewCount( myGDALBand );
+            ++myOverviewCount )
+      {
+        GDALRasterBandH myOverview;
+        myOverview = GDALGetOverview( myGDALBand, myOverviewCount );
+        int myOverviewXDim = GDALGetRasterBandXSize( myOverview );
+        int myOverviewYDim = GDALGetRasterBandYSize( myOverview );
+        //
+        // here is where we check if its a near match:
+        // we will see if its within 5 cells either side of
+        //
+        QgsDebugMsg( "Checking whether " + QString::number( myRasterPyramid.xDim ) + " x " +
+                     QString::number( myRasterPyramid.yDim ) + " matches " +
+                     QString::number( myOverviewXDim ) + " x " + QString::number( myOverviewYDim ) );
+
+
+        if (( myOverviewXDim <= ( myRasterPyramid.xDim + myNearMatchLimit ) ) &&
+            ( myOverviewXDim >= ( myRasterPyramid.xDim - myNearMatchLimit ) ) &&
+            ( myOverviewYDim <= ( myRasterPyramid.yDim + myNearMatchLimit ) ) &&
+            ( myOverviewYDim >= ( myRasterPyramid.yDim - myNearMatchLimit ) ) )
+        {
+          //right we have a match so adjust the a / y before they get added to the list
+          myRasterPyramid.xDim = myOverviewXDim;
+          myRasterPyramid.yDim = myOverviewYDim;
+          myRasterPyramid.exists = true;
+          QgsDebugMsg( ".....YES!" );
+        }
+        else
+        {
+          //no match
+          QgsDebugMsg( ".....no." );
+        }
+      }
+    }
+    mPyramidList.append( myRasterPyramid );
+    //sqare the divisor each step
+    myDivisor = ( myDivisor * 2 );
+  }
+
+  return mPyramidList;
+}
+
+QStringList QgsGdalProvider::subLayers() const
+{
+  return subLayers( mGdalDataset );
+}
+
+
 /**
+ * Class factory to return a pointer to a newly created
+ * QgsGdalProvider object
+ */
+QGISEXTERN QgsGdalProvider * classFactory( const QString *uri )
+{
+  return new QgsGdalProvider( *uri );
+}
+/** Required key function (used to map the plugin to a data store type)
+*/
+QGISEXTERN QString providerKey()
+{
+  return PROVIDER_KEY;
+}
+/**
+ * Required description function
+ */
+QGISEXTERN QString description()
+{
+  return PROVIDER_DESCRIPTION;
+}
+/**
+ * Required isProvider function. Used to determine if this shared library
+ * is a data provider plugin
+ */
+QGISEXTERN bool isProvider()
+{
+  return true;
+}
+
+/**
   Builds the list of file filter strings to later be used by
   QgisApp::addRasterLayer()
 
@@ -673,7 +1236,7 @@
   QFileDialog::getOpenFileNames() call.
 
 */
-void QgsGdalProvider::buildSupportedRasterFileFilter( QString & theFileFiltersString )
+QGISEXTERN void buildSupportedRasterFileFilter( QString & theFileFiltersString )
 {
   QgsDebugMsg("Entered");
   // first get the GDAL driver manager
@@ -843,33 +1406,35 @@
   QgsDebugMsg( "Raster filter list built: " + theFileFiltersString );
 }                               // buildSupportedRasterFileFilter_()
 
-/**
- * Class factory to return a pointer to a newly created
- * QgsGdalProvider object
- */
-QGISEXTERN QgsGdalProvider * classFactory( const QString *uri )
+QGISEXTERN bool isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg )
 {
-  return new QgsGdalProvider( *uri );
+  GDALDatasetH myDataset;
+
+  CPLErrorReset();
+
+  //open the file using gdal making sure we have handled locale properly
+  myDataset = GDALOpen( QFile::encodeName( theFileNameQString ).constData(), GA_ReadOnly );
+  if ( myDataset == NULL )
+  {
+    if ( CPLGetLastErrorNo() != CPLE_OpenFailed )
+      retErrMsg = QString::fromUtf8( CPLGetLastErrorMsg() );
+    return false;
+  }
+  else if ( GDALGetRasterCount( myDataset ) == 0 )
+  {
+    QStringList layers = subLayers( myDataset );
+    if ( layers.size() == 0 )
+    {
+      GDALClose( myDataset );
+      myDataset = NULL;
+      retErrMsg = QObject::tr( "This raster file has no bands and is invalid as a raster layer." );
+      return false;
+    }
+    return true;
+  }
+  else
+  {
+    GDALClose( myDataset );
+    return true;
+  }
 }
-/** Required key function (used to map the plugin to a data store type)
-*/
-QGISEXTERN QString providerKey()
-{
-  return PROVIDER_KEY;
-}
-/**
- * Required description function
- */
-QGISEXTERN QString description()
-{
-  return PROVIDER_DESCRIPTION;
-}
-/**
- * Required isProvider function. Used to determine if this shared library
- * is a data provider plugin
- */
-QGISEXTERN bool isProvider()
-{
-  return true;
-}
-

Modified: branches/raster-providers/src/providers/gdal/qgsgdalprovider.h
===================================================================
--- branches/raster-providers/src/providers/gdal/qgsgdalprovider.h	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/providers/gdal/qgsgdalprovider.h	2010-11-14 18:14:56 UTC (rev 14650)
@@ -33,6 +33,8 @@
 #include <QMap>
 #include <QVector>
 
+class QgsRasterPyramid;
+
 #define CPL_SUPRESS_CPLUSPLUS
 #include <gdal.h>
 
@@ -224,8 +226,33 @@
     /** \brief ensures that GDAL drivers are registered, but only once */
     static void registerGdalDrivers();
 
-    void buildSupportedRasterFileFilter( QString & theFileFiltersString ); 
+    //void buildSupportedRasterFileFilter( QString & theFileFiltersString ); 
 
+    //bool isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg );
+
+    //bool isValidRasterFileName( const QString & theFileNameQString );
+
+    static QStringList subLayers( GDALDatasetH dataset );
+
+    /** \brief Returns the sublayers of this layer - Useful for providers that manage their own layers, such as WMS */
+    QStringList subLayers() const;
+
+    void populateHistogram( int theBandNoInt,
+                    QgsRasterBandStats & theBandStats,
+                    int theBinCountInt = 256,
+                    bool theIgnoreOutOfRangeFlag = true,
+                    bool theThoroughBandScanFlag = false
+                     );
+
+    QString buildPyramids( const QList<QgsRasterPyramid> &,
+                           const QString &  theResamplingMethod = "NEAREST",
+                           bool theTryInternalFlag = false );
+    QList<QgsRasterPyramid> buildPyramidList();
+
+    /** \brief Close data set and release related data */
+    void closeDataset();
+
+
   private:
 
     /**
@@ -270,6 +297,8 @@
 
     QgsCoordinateReferenceSystem mCrs;
 
+    QList<QgsRasterPyramid> mPyramidList;
+
 };
 
 #endif

Modified: branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp
===================================================================
--- branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.cpp	2010-11-14 18:14:56 UTC (rev 14650)
@@ -386,6 +386,16 @@
   return myMetadata;
 }
 
+void populateHistogram( int theBandNoInt,
+                    QgsRasterBandStats & theBandStats,
+                    int theBinCountInt = 256,
+                    bool theIgnoreOutOfRangeFlag = true,
+                    bool theThoroughBandScanFlag = false)
+{
+  // TODO
+}
+
+
 bool QgsGrassRasterProvider::isValid()
 {
   return mValid;
@@ -421,9 +431,9 @@
   return PROVIDER_DESCRIPTION;
 }
 
-void QgsGrassRasterProvider::buildSupportedRasterFileFilter( QString & theFileFiltersString )
-{
-}
+//void QgsGrassRasterProvider::buildSupportedRasterFileFilter( QString & theFileFiltersString )
+//{
+//}
 
 /**
  * Class factory to return a pointer to a newly created

Modified: branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h
===================================================================
--- branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h	2010-11-14 18:00:42 UTC (rev 14649)
+++ branches/raster-providers/src/providers/grass/qgsgrassrasterprovider.h	2010-11-14 18:14:56 UTC (rev 14650)
@@ -199,7 +199,7 @@
 
     QList<QgsColorRampShader::ColorRampItem> colorTable(int bandNo)const;
 
-    void buildSupportedRasterFileFilter( QString & theFileFiltersString );
+   // void buildSupportedRasterFileFilter( QString & theFileFiltersString );
 
     /**
      * Get metadata in a format suitable for feeding directly



More information about the QGIS-commit mailing list