Skip to content

Commit 76b29dc

Browse files
committedMay 23, 2019
If an error occurs while reading raster block data, don't return
corrupt data as a result. Instead, indicate explicitly that an error occurred so that callers will fallback on appropriate error paths. Fixes rendering random junk (and possible crashes) when attempting to open an invalid gdal raster data source, such as the one attached to OSGeo/gdal#1545 Also replace manual memory management with unique_ptrs (cherry picked from commit 230c62f)
1 parent fa2ae2f commit 76b29dc

File tree

10 files changed

+77
-52
lines changed

10 files changed

+77
-52
lines changed
 

‎src/core/raster/qgsrasterdataprovider.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
4646
QgsDebugMsgLevel( QStringLiteral( "bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
4747
QgsDebugMsgLevel( QStringLiteral( "boundingBox = %1" ).arg( boundingBox.toString() ), 4 );
4848

49-
QgsRasterBlock *block = new QgsRasterBlock( dataType( bandNo ), width, height );
49+
std::unique_ptr< QgsRasterBlock > block = qgis::make_unique< QgsRasterBlock >( dataType( bandNo ), width, height );
5050
if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
5151
{
5252
block->setNoDataValue( sourceNoDataValue( bandNo ) );
@@ -55,7 +55,7 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
5555
if ( block->isEmpty() )
5656
{
5757
QgsDebugMsg( QStringLiteral( "Couldn't create raster block" ) );
58-
return block;
58+
return block.release();
5959
}
6060

6161
// Read necessary extent only
@@ -65,7 +65,7 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
6565
{
6666
QgsDebugMsg( QStringLiteral( "Extent outside provider extent" ) );
6767
block->setIsNoData();
68-
return block;
68+
return block.release();
6969
}
7070

7171
double xRes = boundingBox.width() / width;
@@ -112,7 +112,7 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
112112
{
113113
// Should not happen
114114
QgsDebugMsg( QStringLiteral( "Row or column limits out of range" ) );
115-
return block;
115+
return block.release();
116116
}
117117

118118
// If lower source resolution is used, the extent must beS aligned to original
@@ -139,13 +139,18 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
139139
QgsDebugMsgLevel( QStringLiteral( "Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
140140
QgsDebugMsgLevel( QStringLiteral( "tmpExtent = %1" ).arg( tmpExtent.toString() ), 4 );
141141

142-
QgsRasterBlock *tmpBlock = new QgsRasterBlock( dataType( bandNo ), tmpWidth, tmpHeight );
142+
std::unique_ptr< QgsRasterBlock > tmpBlock = qgis::make_unique< QgsRasterBlock >( dataType( bandNo ), tmpWidth, tmpHeight );
143143
if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
144144
{
145145
tmpBlock->setNoDataValue( sourceNoDataValue( bandNo ) );
146146
}
147147

148-
readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback );
148+
if ( !readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ) )
149+
{
150+
QgsDebugMsg( QStringLiteral( "Error occurred while reading block" ) );
151+
block->setIsNoData();
152+
return block.release();
153+
}
149154

150155
int pixelSize = dataTypeSize( bandNo );
151156

@@ -168,8 +173,7 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
168173
{
169174
QgsDebugMsg( QStringLiteral( "Source row or column limits out of range" ) );
170175
block->setIsNoData(); // so that the problem becomes obvious and fixed
171-
delete tmpBlock;
172-
return block;
176+
return block.release();
173177
}
174178

175179
qgssize tmpIndex = static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
@@ -190,19 +194,22 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
190194
memcpy( bits, tmpBits, pixelSize );
191195
}
192196
}
193-
194-
delete tmpBlock;
195197
}
196198
else
197199
{
198-
readBlock( bandNo, boundingBox, width, height, block->bits(), feedback );
200+
if ( !readBlock( bandNo, boundingBox, width, height, block->bits(), feedback ) )
201+
{
202+
QgsDebugMsg( QStringLiteral( "Error occurred while reading block" ) );
203+
block->setIsNoData();
204+
return block.release();
205+
}
199206
}
200207

201208
// apply scale and offset
202209
block->applyScaleOffset( bandScale( bandNo ), bandOffset( bandNo ) );
203210
// apply user no data values
204211
block->applyNoDataValues( userNoDataValues( bandNo ) );
205-
return block;
212+
return block.release();
206213
}
207214

208215
QgsRasterDataProvider::QgsRasterDataProvider()

‎src/core/raster/qgsrasterdataprovider.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,15 +538,15 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
538538
* Read block of data
539539
* \note not available in Python bindings
540540
*/
541-
virtual void readBlock( int bandNo, int xBlock, int yBlock, void *data ) SIP_SKIP
542-
{ Q_UNUSED( bandNo ); Q_UNUSED( xBlock ); Q_UNUSED( yBlock ); Q_UNUSED( data ); }
541+
virtual bool readBlock( int bandNo, int xBlock, int yBlock, void *data ) SIP_SKIP
542+
{ Q_UNUSED( bandNo ) Q_UNUSED( xBlock ); Q_UNUSED( yBlock ); Q_UNUSED( data ); return false; }
543543

544544
/**
545545
* Read block of data using give extent and size
546546
* \note not available in Python bindings
547547
*/
548-
virtual void readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) SIP_SKIP
549-
{ Q_UNUSED( bandNo ); Q_UNUSED( viewExtent ); Q_UNUSED( width ); Q_UNUSED( height ); Q_UNUSED( data ); Q_UNUSED( feedback ); }
548+
virtual bool readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) SIP_SKIP
549+
{ Q_UNUSED( bandNo ) Q_UNUSED( viewExtent ); Q_UNUSED( width ); Q_UNUSED( height ); Q_UNUSED( data ); Q_UNUSED( feedback ); return false; }
550550

551551
//! Returns true if user no data contains value
552552
bool userNoDataValuesContains( int bandNo, double value ) const;

‎src/providers/arcgisrest/qgsamsprovider.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ QgsRasterIdentifyResult QgsAmsProvider::identify( const QgsPointXY &point, QgsRa
454454
return QgsRasterIdentifyResult( format, entries );
455455
}
456456

457-
void QgsAmsProvider::readBlock( int /*bandNo*/, const QgsRectangle &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback )
457+
bool QgsAmsProvider::readBlock( int /*bandNo*/, const QgsRectangle &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback )
458458
{
459459
Q_UNUSED( feedback ); // TODO: make use of the feedback object
460460

@@ -463,9 +463,10 @@ void QgsAmsProvider::readBlock( int /*bandNo*/, const QgsRectangle &viewExtent,
463463
if ( mCachedImage.width() != width || mCachedImage.height() != height )
464464
{
465465
QgsDebugMsg( QStringLiteral( "Unexpected image size for block" ) );
466-
return;
466+
return false;
467467
}
468468
std::memcpy( data, mCachedImage.constBits(), mCachedImage.bytesPerLine() * mCachedImage.height() );
469+
return true;
469470
}
470471

471472
#ifdef HAVE_GUI

‎src/providers/arcgisrest/qgsamsprovider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class QgsAmsProvider : public QgsRasterDataProvider
8686
QgsRasterIdentifyResult identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &extent = QgsRectangle(), int width = 0, int height = 0, int dpi = 96 ) override;
8787

8888
protected:
89-
void readBlock( int bandNo, const QgsRectangle &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
89+
bool readBlock( int bandNo, const QgsRectangle &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
9090

9191
void draw( const QgsRectangle &viewExtent, int pixelWidth, int pixelHeight );
9292

‎src/providers/gdal/qgsgdalprovider.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -644,43 +644,48 @@ QString QgsGdalProvider::htmlMetadata()
644644

645645
QgsRasterBlock *QgsGdalProvider::block( int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback )
646646
{
647-
QgsRasterBlock *block = new QgsRasterBlock( dataType( bandNo ), width, height );
647+
std::unique_ptr< QgsRasterBlock > block = qgis::make_unique< QgsRasterBlock >( dataType( bandNo ), width, height );
648648
if ( !initIfNeeded() )
649-
return block;
649+
return block.release();
650650
if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
651651
{
652652
block->setNoDataValue( sourceNoDataValue( bandNo ) );
653653
}
654654

655655
if ( block->isEmpty() )
656656
{
657-
return block;
657+
return block.release();
658658
}
659659

660660
if ( !mExtent.intersects( extent ) )
661661
{
662662
// the requested extent is completely outside of the raster's extent - nothing to do
663663
block->setIsNoData();
664-
return block;
664+
return block.release();
665665
}
666666

667667
if ( !mExtent.contains( extent ) )
668668
{
669669
QRect subRect = QgsRasterBlock::subRect( extent, width, height, mExtent );
670670
block->setIsNoDataExcept( subRect );
671671
}
672-
readBlock( bandNo, extent, width, height, block->bits(), feedback );
672+
if ( !readBlock( bandNo, extent, width, height, block->bits(), feedback ) )
673+
{
674+
QgsDebugMsg( QStringLiteral( "Error occurred while reading block" ) );
675+
block->setIsNoData();
676+
return block.release();
677+
}
673678
// apply scale and offset
674679
block->applyScaleOffset( bandScale( bandNo ), bandOffset( bandNo ) );
675680
block->applyNoDataValues( userNoDataValues( bandNo ) );
676-
return block;
681+
return block.release();
677682
}
678683

679-
void QgsGdalProvider::readBlock( int bandNo, int xBlock, int yBlock, void *data )
684+
bool QgsGdalProvider::readBlock( int bandNo, int xBlock, int yBlock, void *data )
680685
{
681686
QMutexLocker locker( mpMutex );
682687
if ( !initIfNeeded() )
683-
return;
688+
return false;
684689

685690
// TODO!!!: Check data alignment!!! May it happen that nearest value which
686691
// is not nearest is assigned to an output cell???
@@ -694,14 +699,21 @@ void QgsGdalProvider::readBlock( int bandNo, int xBlock, int yBlock, void *data
694699
// We have to read with correct data type consistent with other readBlock functions
695700
int xOff = xBlock * mXBlockSize;
696701
int yOff = yBlock * mYBlockSize;
697-
gdalRasterIO( myGdalBand, GF_Read, xOff, yOff, mXBlockSize, mYBlockSize, data, mXBlockSize, mYBlockSize, ( GDALDataType ) mGdalDataType.at( bandNo - 1 ), 0, 0 );
702+
CPLErr err = gdalRasterIO( myGdalBand, GF_Read, xOff, yOff, mXBlockSize, mYBlockSize, data, mXBlockSize, mYBlockSize, ( GDALDataType ) mGdalDataType.at( bandNo - 1 ), 0, 0 );
703+
if ( err != CPLE_None )
704+
{
705+
QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
706+
return false;
707+
}
708+
709+
return true;
698710
}
699711

700-
void QgsGdalProvider::readBlock( int bandNo, QgsRectangle const &extent, int pixelWidth, int pixelHeight, void *data, QgsRasterBlockFeedback *feedback )
712+
bool QgsGdalProvider::readBlock( int bandNo, QgsRectangle const &extent, int pixelWidth, int pixelHeight, void *data, QgsRasterBlockFeedback *feedback )
701713
{
702714
QMutexLocker locker( mpMutex );
703715
if ( !initIfNeeded() )
704-
return;
716+
return false;
705717

706718
QgsDebugMsgLevel( "pixelWidth = " + QString::number( pixelWidth ), 5 );
707719
QgsDebugMsgLevel( "pixelHeight = " + QString::number( pixelHeight ), 5 );
@@ -734,7 +746,7 @@ void QgsGdalProvider::readBlock( int bandNo, QgsRectangle const &extent, int pi
734746
if ( rasterExtent.isEmpty() )
735747
{
736748
QgsDebugMsg( QStringLiteral( "draw request outside view extent." ) );
737-
return;
749+
return false;
738750
}
739751
QgsDebugMsgLevel( "extent: " + mExtent.toString(), 5 );
740752
QgsDebugMsgLevel( "rasterExtent: " + rasterExtent.toString(), 5 );
@@ -878,7 +890,7 @@ void QgsGdalProvider::readBlock( int bandNo, QgsRectangle const &extent, int pi
878890
if ( ! tmpBlock )
879891
{
880892
QgsDebugMsgLevel( QStringLiteral( "Couldn't allocate temporary buffer of %1 bytes" ).arg( dataSize * tmpWidth * tmpHeight ), 5 );
881-
return;
893+
return false;
882894
}
883895
GDALRasterBandH gdalBand = getBand( bandNo );
884896
GDALDataType type = static_cast<GDALDataType>( mGdalDataType.at( bandNo - 1 ) );
@@ -894,7 +906,7 @@ void QgsGdalProvider::readBlock( int bandNo, QgsRectangle const &extent, int pi
894906
{
895907
QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
896908
qgsFree( tmpBlock );
897-
return;
909+
return false;
898910
}
899911

900912
double tmpXRes = srcWidth * srcXRes / tmpWidth;
@@ -932,6 +944,7 @@ void QgsGdalProvider::readBlock( int bandNo, QgsRectangle const &extent, int pi
932944
}
933945

934946
qgsFree( tmpBlock );
947+
return true;
935948
}
936949

937950
/**

‎src/providers/gdal/qgsgdalprovider.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
120120
// Reimplemented from QgsRasterDataProvider to bypass second resampling (more efficient for local file based sources)
121121
QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback = nullptr ) override;
122122

123-
void readBlock( int bandNo, int xBlock, int yBlock, void *data ) override;
124-
void readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
123+
bool readBlock( int bandNo, int xBlock, int yBlock, void *data ) override;
124+
bool readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
125125
double bandScale( int bandNo ) const override;
126126
double bandOffset( int bandNo ) const override;
127127
QList<QgsColorRampShader::ColorRampItem> colorTable( int bandNo )const override;

‎src/providers/wcs/qgswcsprovider.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ void QgsWcsProvider::setQueryItem( QUrl &url, const QString &item, const QString
476476
url.addQueryItem( item, value );
477477
}
478478

479-
void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int pixelWidth, int pixelHeight, void *block, QgsRasterBlockFeedback *feedback )
479+
bool QgsWcsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int pixelWidth, int pixelHeight, void *block, QgsRasterBlockFeedback *feedback )
480480
{
481481
// TODO: set block to null values, move that to function and call only if fails
482482
memset( block, 0, pixelWidth * pixelHeight * QgsRasterBlock::typeSize( dataType( bandNo ) ) );
@@ -486,7 +486,7 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int
486486
// (higher level checks) but it is better to do check here as well
487487
if ( !viewExtent.intersects( mCoverageExtent ) )
488488
{
489-
return;
489+
return false;
490490
}
491491

492492
// Can we reuse the previously cached coverage?
@@ -532,7 +532,7 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int
532532
// If it happens, it would be possible to rescale the portion we get
533533
// to only part of the data block, but it is better to left it
534534
// blank, so that the problem may be discovered in its origin.
535-
return;
535+
return false;
536536
}
537537
}
538538

@@ -554,7 +554,7 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int
554554
if ( ! tmpData )
555555
{
556556
QgsDebugMsg( QStringLiteral( "Couldn't allocate memory of %1 bytes" ).arg( size ) );
557-
return;
557+
return false;
558558
}
559559
if ( GDALRasterIO( gdalBand, GF_Read, 0, 0, width, height, tmpData, width, height, ( GDALDataType ) mGdalDataType.at( bandNo - 1 ), 0, 0 ) != CE_None )
560560
{
@@ -592,6 +592,7 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int
592592
QgsMessageLog::logMessage( tr( "Received coverage has wrong size %1 x %2 (expected %3 x %4)" ).arg( width ).arg( height ).arg( pixelWidth ).arg( pixelHeight ), tr( "WCS" ) );
593593
}
594594
}
595+
return true;
595596
}
596597

597598
void QgsWcsProvider::getCache( int bandNo, QgsRectangle const &viewExtent, int pixelWidth, int pixelHeight, QString crs, QgsRasterBlockFeedback *feedback ) const
@@ -795,12 +796,13 @@ void QgsWcsProvider::getCache( int bandNo, QgsRectangle const &viewExtent, int
795796

796797
// For stats only, maybe change QgsRasterDataProvider::bandStatistics() to
797798
// use standard readBlock with extent
798-
void QgsWcsProvider::readBlock( int bandNo, int xBlock, int yBlock, void *block )
799+
bool QgsWcsProvider::readBlock( int bandNo, int xBlock, int yBlock, void *block )
799800
{
800801

801802
QgsDebugMsg( QStringLiteral( "xBlock = %1 yBlock = %2" ).arg( xBlock ).arg( yBlock ) );
802803

803-
if ( !mHasSize ) return;
804+
if ( !mHasSize )
805+
return false;
804806

805807
double xRes = mCoverageExtent.width() / mWidth;
806808
double yRes = mCoverageExtent.height() / mHeight;
@@ -815,7 +817,7 @@ void QgsWcsProvider::readBlock( int bandNo, int xBlock, int yBlock, void *block
815817

816818
QgsRectangle extent( xMin, yMin, xMax, yMax );
817819

818-
readBlock( bandNo, extent, mXBlockSize, mYBlockSize, block, nullptr );
820+
return readBlock( bandNo, extent, mXBlockSize, mYBlockSize, block, nullptr );
819821
}
820822

821823

‎src/providers/wcs/qgswcsprovider.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ class QgsWcsProvider : public QgsRasterDataProvider, QgsGdalProviderBase
144144

145145
// TODO: Document this better.
146146

147-
void readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
147+
bool readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
148148

149-
void readBlock( int bandNo, int xBlock, int yBlock, void *block ) override;
149+
bool readBlock( int bandNo, int xBlock, int yBlock, void *block ) override;
150150

151151
//! Download cache
152152
void getCache( int bandNo, QgsRectangle const &viewExtent, int width, int height, QString crs = QString(), QgsRasterBlockFeedback *feedback = nullptr ) const;

‎src/providers/wms/qgswmsprovider.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -883,15 +883,15 @@ QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, in
883883
return image;
884884
}
885885

886-
void QgsWmsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int pixelWidth, int pixelHeight, void *block, QgsRasterBlockFeedback *feedback )
886+
bool QgsWmsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int pixelWidth, int pixelHeight, void *block, QgsRasterBlockFeedback *feedback )
887887
{
888888
Q_UNUSED( bandNo );
889889
// TODO: optimize to avoid writing to QImage
890-
QImage *image = draw( viewExtent, pixelWidth, pixelHeight, feedback );
890+
std::unique_ptr< QImage > image( draw( viewExtent, pixelWidth, pixelHeight, feedback ) );
891891
if ( !image ) // should not happen
892892
{
893893
QgsMessageLog::logMessage( tr( "image is NULL" ), tr( "WMS" ) );
894-
return;
894+
return false;
895895
}
896896

897897
QgsDebugMsg( QStringLiteral( "image height = %1 bytesPerLine = %2" ).arg( image->height() ) . arg( image->bytesPerLine() ) );
@@ -900,18 +900,20 @@ void QgsWmsProvider::readBlock( int bandNo, QgsRectangle const &viewExtent, int
900900
if ( myExpectedSize != myImageSize ) // should not happen
901901
{
902902
QgsMessageLog::logMessage( tr( "unexpected image size" ), tr( "WMS" ) );
903-
delete image;
904-
return;
903+
return false;
905904
}
906905

907906
uchar *ptr = image->bits();
908907
if ( ptr )
909908
{
910909
// If image is too large, ptr can be NULL
911910
memcpy( block, ptr, myExpectedSize );
911+
return true;
912+
}
913+
else
914+
{
915+
return false;
912916
}
913-
914-
delete image;
915917
}
916918

917919
QUrl QgsWmsProvider::createRequestUrlWMS( const QgsRectangle &viewExtent, int pixelWidth, int pixelHeight )

‎src/providers/wms/qgswmsprovider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class QgsWmsProvider : public QgsRasterDataProvider
146146
*/
147147
void setConnectionName( QString const &connName );
148148

149-
void readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
149+
bool readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
150150
//void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, QgsCoordinateReferenceSystem srcCRS, QgsCoordinateReferenceSystem destCRS, void *data );
151151

152152
QgsRectangle extent() const override;

0 commit comments

Comments
 (0)
Please sign in to comment.