Skip to content

Commit 05dfe8b

Browse files
author
homann
committedFeb 15, 2007
Fix for bug #574. Checking for out-of-memory when allocating data buffer for rasterIO,
and also trying to avoid too high zoom level. In either case, the raster does not get displayed. git-svn-id: http://svn.osgeo.org/qgis/branches/Release-0_8_0@6598 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 5fb5d1e commit 05dfe8b

File tree

1 file changed

+93
-14
lines changed

1 file changed

+93
-14
lines changed
 

‎src/raster/qgsrasterlayer.cpp

Lines changed: 93 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,7 @@ __FUNCTION__, __LINE__);
11811181
myRasterViewPort->drawableAreaYDimInt =
11821182
abs(static_cast<int> (myRasterViewPort->clippedHeightInt / theQgsMapToPixel->mapUnitsPerPixel() * adfGeoTransform[5]));
11831183

1184+
11841185
#ifdef QGISDEBUG
11851186
QgsLogger::debug("QgsRasterLayer::draw: mapUnitsPerPixel", theQgsMapToPixel->mapUnitsPerPixel(), 1, __FILE__,\
11861187
__FUNCTION__, __LINE__);
@@ -1240,7 +1241,15 @@ __FUNCTION__, __LINE__);
12401241

12411242
// /\/\/\ - added to handle zoomed-in rasters
12421243

1243-
1244+
if ((myRasterViewPort->drawableAreaXDimInt) > 4000 && (myRasterViewPort->drawableAreaYDimInt > 4000))
1245+
{
1246+
// We have scale one raster pixel to more than 4000 screen pixels. What's the point of showing this layer?
1247+
// Instead, we just stop displaying the layer. Prevents allocating the entire world of memory for showing
1248+
// The pixel in all its glory.
1249+
QgsDebugMsg("Too zoomed out! Raster will not display");
1250+
return TRUE;
1251+
}
1252+
12441253
// Provider mode: See if a provider key is specified, and if so use the provider instead
12451254

12461255
QgsDebugMsg("QgsRasterLayer::draw: Checking for provider key.");
@@ -1337,7 +1346,6 @@ void QgsRasterLayer::draw(QPainter * theQPainter,
13371346
// procedure to use :
13381347
//
13391348

1340-
13411349
switch (drawingStyle)
13421350
{
13431351
// a "Gray" or "Undefined" layer drawn as a range of gray colors
@@ -1445,7 +1453,7 @@ void QgsRasterLayer::draw(QPainter * theQPainter,
14451453
break;
14461454

14471455
}
1448-
1456+
14491457
//see if debug info is wanted
14501458
if (showDebugOverlayFlag)
14511459
{
@@ -1463,6 +1471,12 @@ void QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, QgsRasterViewPor
14631471
GDALDataType myDataType = myGdalBand->GetRasterDataType();
14641472
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );
14651473

1474+
/* Check for out of memory error */
1475+
if (myGdalScanData == NULL)
1476+
{
1477+
return;
1478+
}
1479+
14661480
QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
14671481
//myQImage.fill(0);
14681482
myQImage.setAlphaBuffer(true);
@@ -1500,6 +1514,8 @@ void QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, QgsRasterViewPor
15001514
myQImage.setPixel(myRowInt, myColumnInt, qRgba(myGrayValInt, myGrayValInt, myGrayValInt, transparencyLevelInt));
15011515
}
15021516
}
1517+
1518+
/* TODO: Should readData be freed here? */
15031519

15041520
//render any inline filters
15051521
filterLayer(&myQImage);
@@ -1555,6 +1571,12 @@ void QgsRasterLayer::drawSingleBandPseudoColor(QPainter * theQPainter,
15551571
GDALDataType myDataType = myGdalBand->GetRasterDataType();
15561572
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );
15571573

1574+
/* Check for out of memory error */
1575+
if (myGdalScanData == NULL)
1576+
{
1577+
return;
1578+
}
1579+
15581580
QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
15591581
//myQImage.fill(0);
15601582
myQImage.setAlphaBuffer(true);
@@ -1772,6 +1794,13 @@ void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, QgsRast
17721794
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
17731795
GDALDataType myDataType = myGdalBand->GetRasterDataType();
17741796
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );
1797+
1798+
/* Check for out of memory error */
1799+
if (myGdalScanData == NULL)
1800+
{
1801+
return;
1802+
}
1803+
17751804
QgsColorTable *myColorTable = colorTable ( theBandNoInt );
17761805

17771806
QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
@@ -1802,6 +1831,9 @@ void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, QgsRast
18021831
myQImage.setPixel(myRowInt, myColumnInt, qRgba(c1, c2, c3, transparencyLevelInt));
18031832
}
18041833
}
1834+
1835+
/* TODO: Should readData be freed here? */
1836+
18051837
//render any inline filters
18061838
filterLayer(&myQImage);
18071839

@@ -1862,6 +1894,13 @@ void QgsRasterLayer::drawPalettedSingleBandGray(QPainter * theQPainter, QgsRaste
18621894
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
18631895
GDALDataType myDataType = myGdalBand->GetRasterDataType();
18641896
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );
1897+
1898+
/* Check for out of memory error */
1899+
if (myGdalScanData == NULL)
1900+
{
1901+
return;
1902+
}
1903+
18651904
QgsColorTable *myColorTable = &(myRasterBandStats.colorTable);
18661905

18671906
QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
@@ -1966,6 +2005,13 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor(QPainter * theQPainter, Q
19662005
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
19672006
GDALDataType myDataType = myGdalBand->GetRasterDataType();
19682007
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );
2008+
2009+
/* Check for out of memory error */
2010+
if (myGdalScanData == NULL)
2011+
{
2012+
return;
2013+
}
2014+
19692015
QgsColorTable *myColorTable = &(myRasterBandStats.colorTable);
19702016

19712017
QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
@@ -2202,6 +2248,13 @@ void QgsRasterLayer::drawPalettedMultiBandColor(QPainter * theQPainter, QgsRaste
22022248
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
22032249
GDALDataType myDataType = myGdalBand->GetRasterDataType();
22042250
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );
2251+
2252+
/* Check for out of memory error */
2253+
if (myGdalScanData == NULL)
2254+
{
2255+
return;
2256+
}
2257+
22052258
QgsColorTable *myColorTable = colorTable ( theBandNoInt );
22062259

22072260
QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
@@ -2340,6 +2393,16 @@ void QgsRasterLayer::drawMultiBandColor(QPainter * theQPainter, QgsRasterViewPor
23402393
void *myGdalGreenData = readData ( myGdalGreenBand, theRasterViewPort );
23412394
void *myGdalBlueData = readData ( myGdalBlueBand, theRasterViewPort );
23422395

2396+
/* Check for out of memory error */
2397+
if (myGdalRedData == NULL || myGdalGreenData == NULL || myGdalBlueData == NULL)
2398+
{
2399+
// Safe to free NULL-pointer */
2400+
VSIFree(myGdalRedData);
2401+
VSIFree(myGdalGreenData);
2402+
VSIFree(myGdalBlueData);
2403+
return;
2404+
}
2405+
23432406
bool haveTransparencyBand(false);
23442407
GDALRasterBand *myGdalTransparentBand;
23452408
GDALDataType myTransparentType;
@@ -2352,6 +2415,14 @@ void QgsRasterLayer::drawMultiBandColor(QPainter * theQPainter, QgsRasterViewPor
23522415
myGdalTransparentBand = gdalDataset->GetRasterBand(myTransparentBandNoInt);
23532416
myTransparentType = myGdalTransparentBand->GetRasterDataType();
23542417
myGdalTransparentData = readData ( myGdalTransparentBand, theRasterViewPort );
2418+
if (myGdalTransparentData == NULL)
2419+
{
2420+
// Safe to free NULL-pointer */
2421+
VSIFree(myGdalRedData);
2422+
VSIFree(myGdalGreenData);
2423+
VSIFree(myGdalBlueData);
2424+
return;
2425+
}
23552426
}
23562427

23572428
QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
@@ -4410,8 +4481,6 @@ void *QgsRasterLayer::readData ( GDALRasterBand *gdalBand, QgsRasterViewPort *vi
44104481
GDALDataType type = gdalBand->GetRasterDataType();
44114482
int size = GDALGetDataTypeSize ( type ) / 8;
44124483

4413-
void *data = CPLMalloc ( size * viewPort->drawableAreaXDimInt * viewPort->drawableAreaYDimInt );
4414-
44154484
QgsDebugMsg("QgsRasterLayer::readData: calling RasterIO with " +\
44164485
QString(", source NW corner: ") + QString::number(viewPort->rectXOffsetInt)+\
44174486
", " + QString::number(viewPort->rectYOffsetInt)+\
@@ -4420,16 +4489,26 @@ void *QgsRasterLayer::readData ( GDALRasterBand *gdalBand, QgsRasterViewPort *vi
44204489
", dest size: " + QString::number(viewPort->drawableAreaXDimInt)+\
44214490
", " + QString::number(viewPort->drawableAreaYDimInt));
44224491

4423-
CPLErr myErr = gdalBand->RasterIO ( GF_Read,
4424-
viewPort->rectXOffsetInt,
4425-
viewPort->rectYOffsetInt,
4426-
viewPort->clippedWidthInt,
4427-
viewPort->clippedHeightInt,
4428-
data,
4429-
viewPort->drawableAreaXDimInt,
4430-
viewPort->drawableAreaYDimInt,
4431-
type, 0, 0 );
4492+
void *data = VSIMalloc ( size * viewPort->drawableAreaXDimInt * viewPort->drawableAreaYDimInt );
4493+
4494+
/* Abort if out of memory */
4495+
if (data == NULL)
4496+
{
4497+
QgsDebugMsg("Layer " + this->name() + " couldn't allocate enough memory. Ignoring");
4498+
}
4499+
else
4500+
{
4501+
CPLErr myErr = gdalBand->RasterIO ( GF_Read,
4502+
viewPort->rectXOffsetInt,
4503+
viewPort->rectYOffsetInt,
4504+
viewPort->clippedWidthInt,
4505+
viewPort->clippedHeightInt,
4506+
data,
4507+
viewPort->drawableAreaXDimInt,
4508+
viewPort->drawableAreaYDimInt,
4509+
type, 0, 0 );
44324510

4511+
}
44334512
return data;
44344513
}
44354514

0 commit comments

Comments
 (0)
Please sign in to comment.