Skip to content

Commit

Permalink
Fix for bug #574. Checking for out-of-memory when allocating data buf…
Browse files Browse the repository at this point in the history
…fer 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
  • Loading branch information
homann committed Feb 15, 2007
1 parent 5fb5d1e commit 05dfe8b
Showing 1 changed file with 93 additions and 14 deletions.
107 changes: 93 additions & 14 deletions src/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,7 @@ __FUNCTION__, __LINE__);
myRasterViewPort->drawableAreaYDimInt =
abs(static_cast<int> (myRasterViewPort->clippedHeightInt / theQgsMapToPixel->mapUnitsPerPixel() * adfGeoTransform[5]));


#ifdef QGISDEBUG
QgsLogger::debug("QgsRasterLayer::draw: mapUnitsPerPixel", theQgsMapToPixel->mapUnitsPerPixel(), 1, __FILE__,\
__FUNCTION__, __LINE__);
Expand Down Expand Up @@ -1240,7 +1241,15 @@ __FUNCTION__, __LINE__);

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


if ((myRasterViewPort->drawableAreaXDimInt) > 4000 && (myRasterViewPort->drawableAreaYDimInt > 4000))
{
// We have scale one raster pixel to more than 4000 screen pixels. What's the point of showing this layer?
// Instead, we just stop displaying the layer. Prevents allocating the entire world of memory for showing
// The pixel in all its glory.
QgsDebugMsg("Too zoomed out! Raster will not display");
return TRUE;
}

// Provider mode: See if a provider key is specified, and if so use the provider instead

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


switch (drawingStyle)
{
// a "Gray" or "Undefined" layer drawn as a range of gray colors
Expand Down Expand Up @@ -1445,7 +1453,7 @@ void QgsRasterLayer::draw(QPainter * theQPainter,
break;

}

//see if debug info is wanted
if (showDebugOverlayFlag)
{
Expand All @@ -1463,6 +1471,12 @@ void QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, QgsRasterViewPor
GDALDataType myDataType = myGdalBand->GetRasterDataType();
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );

/* Check for out of memory error */
if (myGdalScanData == NULL)
{
return;
}

QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
//myQImage.fill(0);
myQImage.setAlphaBuffer(true);
Expand Down Expand Up @@ -1500,6 +1514,8 @@ void QgsRasterLayer::drawSingleBandGray(QPainter * theQPainter, QgsRasterViewPor
myQImage.setPixel(myRowInt, myColumnInt, qRgba(myGrayValInt, myGrayValInt, myGrayValInt, transparencyLevelInt));
}
}

/* TODO: Should readData be freed here? */

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

/* Check for out of memory error */
if (myGdalScanData == NULL)
{
return;
}

QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
//myQImage.fill(0);
myQImage.setAlphaBuffer(true);
Expand Down Expand Up @@ -1772,6 +1794,13 @@ void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, QgsRast
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
GDALDataType myDataType = myGdalBand->GetRasterDataType();
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );

/* Check for out of memory error */
if (myGdalScanData == NULL)
{
return;
}

QgsColorTable *myColorTable = colorTable ( theBandNoInt );

QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
Expand Down Expand Up @@ -1802,6 +1831,9 @@ void QgsRasterLayer::drawPalettedSingleBandColor(QPainter * theQPainter, QgsRast
myQImage.setPixel(myRowInt, myColumnInt, qRgba(c1, c2, c3, transparencyLevelInt));
}
}

/* TODO: Should readData be freed here? */

//render any inline filters
filterLayer(&myQImage);

Expand Down Expand Up @@ -1862,6 +1894,13 @@ void QgsRasterLayer::drawPalettedSingleBandGray(QPainter * theQPainter, QgsRaste
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
GDALDataType myDataType = myGdalBand->GetRasterDataType();
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );

/* Check for out of memory error */
if (myGdalScanData == NULL)
{
return;
}

QgsColorTable *myColorTable = &(myRasterBandStats.colorTable);

QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
Expand Down Expand Up @@ -1966,6 +2005,13 @@ void QgsRasterLayer::drawPalettedSingleBandPseudoColor(QPainter * theQPainter, Q
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
GDALDataType myDataType = myGdalBand->GetRasterDataType();
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );

/* Check for out of memory error */
if (myGdalScanData == NULL)
{
return;
}

QgsColorTable *myColorTable = &(myRasterBandStats.colorTable);

QImage myQImage = QImage(theRasterViewPort->drawableAreaXDimInt, theRasterViewPort->drawableAreaYDimInt, 32);
Expand Down Expand Up @@ -2202,6 +2248,13 @@ void QgsRasterLayer::drawPalettedMultiBandColor(QPainter * theQPainter, QgsRaste
GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand(theBandNoInt);
GDALDataType myDataType = myGdalBand->GetRasterDataType();
void *myGdalScanData = readData ( myGdalBand, theRasterViewPort );

/* Check for out of memory error */
if (myGdalScanData == NULL)
{
return;
}

QgsColorTable *myColorTable = colorTable ( theBandNoInt );

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

/* Check for out of memory error */
if (myGdalRedData == NULL || myGdalGreenData == NULL || myGdalBlueData == NULL)
{
// Safe to free NULL-pointer */
VSIFree(myGdalRedData);
VSIFree(myGdalGreenData);
VSIFree(myGdalBlueData);
return;
}

bool haveTransparencyBand(false);
GDALRasterBand *myGdalTransparentBand;
GDALDataType myTransparentType;
Expand All @@ -2352,6 +2415,14 @@ void QgsRasterLayer::drawMultiBandColor(QPainter * theQPainter, QgsRasterViewPor
myGdalTransparentBand = gdalDataset->GetRasterBand(myTransparentBandNoInt);
myTransparentType = myGdalTransparentBand->GetRasterDataType();
myGdalTransparentData = readData ( myGdalTransparentBand, theRasterViewPort );
if (myGdalTransparentData == NULL)
{
// Safe to free NULL-pointer */
VSIFree(myGdalRedData);
VSIFree(myGdalGreenData);
VSIFree(myGdalBlueData);
return;
}
}

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

void *data = CPLMalloc ( size * viewPort->drawableAreaXDimInt * viewPort->drawableAreaYDimInt );

QgsDebugMsg("QgsRasterLayer::readData: calling RasterIO with " +\
QString(", source NW corner: ") + QString::number(viewPort->rectXOffsetInt)+\
", " + QString::number(viewPort->rectYOffsetInt)+\
Expand All @@ -4420,16 +4489,26 @@ void *QgsRasterLayer::readData ( GDALRasterBand *gdalBand, QgsRasterViewPort *vi
", dest size: " + QString::number(viewPort->drawableAreaXDimInt)+\
", " + QString::number(viewPort->drawableAreaYDimInt));

CPLErr myErr = gdalBand->RasterIO ( GF_Read,
viewPort->rectXOffsetInt,
viewPort->rectYOffsetInt,
viewPort->clippedWidthInt,
viewPort->clippedHeightInt,
data,
viewPort->drawableAreaXDimInt,
viewPort->drawableAreaYDimInt,
type, 0, 0 );
void *data = VSIMalloc ( size * viewPort->drawableAreaXDimInt * viewPort->drawableAreaYDimInt );

/* Abort if out of memory */
if (data == NULL)
{
QgsDebugMsg("Layer " + this->name() + " couldn't allocate enough memory. Ignoring");
}
else
{
CPLErr myErr = gdalBand->RasterIO ( GF_Read,
viewPort->rectXOffsetInt,
viewPort->rectYOffsetInt,
viewPort->clippedWidthInt,
viewPort->clippedHeightInt,
data,
viewPort->drawableAreaXDimInt,
viewPort->drawableAreaYDimInt,
type, 0, 0 );

}
return data;
}

Expand Down

0 comments on commit 05dfe8b

Please sign in to comment.