Skip to content
Permalink
Browse files

Merge pull request #231 from homann/memcpy_malloc_fixes

Memcpy malloc fixes, should remove some out of mem crashes. Downside, it is still slow... Also fixed a warning about missing copy ctor.
  • Loading branch information
homann committed Sep 13, 2012
2 parents 24a047d + e2e2792 commit d11fd92343910838d4e7aed8d6b99df7e10dde20
@@ -64,7 +64,7 @@ void QgsRasterDataProvider::readBlock( int bandNo, QgsRectangle
return;

// Allocate memory for not projected source data
int mySize = dataTypeSize( bandNo ) / 8;
size_t mySize = dataTypeSize( bandNo ) / 8;
void *mySrcData = malloc( mySize * myProjector.srcRows() * myProjector.srcCols() );

time.restart();
@@ -101,6 +101,11 @@ void * QgsRasterDataProvider::readBlock( int bandNo, QgsRectangle const & exten

// TODO: replace VSIMalloc, it is GDAL function
void * data = VSIMalloc( dataTypeSize( bandNo ) * width * height );
if ( ! data )
{
QgsDebugMsg( QString( "Couldn't allocate data memory of % bytes" ).arg( dataTypeSize( bandNo ) * width * height ) );
return 0;
}
readBlock( bandNo, extent, width, height, data );

return data;
@@ -260,9 +265,9 @@ QString QgsRasterDataProvider::lastErrorFormat()
QByteArray QgsRasterDataProvider::noValueBytes( int theBandNo )
{
int type = dataType( theBandNo );
int size = dataTypeSize( theBandNo ) / 8;
size_t size = dataTypeSize( theBandNo ) / 8;
QByteArray ba;
ba.resize( size );
ba.resize(( int )size );
char * data = ba.data();
double noval = mNoDataValue[theBandNo-1];
unsigned char uc;
@@ -67,6 +67,7 @@ QgsRasterProjector::QgsRasterProjector()
}

QgsRasterProjector::QgsRasterProjector( const QgsRasterProjector &projector )
: QgsRasterInterface( 0 )
{
mSrcCRS = projector.mSrcCRS;
mDestCRS = projector.mDestCRS;
@@ -194,7 +195,7 @@ void QgsRasterProjector::calc()
}
// What is the maximum reasonable size of transformatio matrix?
// TODO: consider better when to break - ratio
if ( mCPRows * mCPCols > 0.0625 * mDestRows * mDestCols )
if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
{
QgsDebugMsg( "Too large CP matrix" );
mApproximate = false;
@@ -679,13 +680,20 @@ void * QgsRasterProjector::readBlock( int bandNo, QgsRectangle const & extent,

if ( !inputData ) return 0;

int pixelSize = mInput->typeSize( mInput->dataType( bandNo ) ) / 8;
size_t pixelSize = mInput->typeSize( mInput->dataType( bandNo ) ) / 8;

int inputSize = pixelSize * srcCols() * srcRows();
size_t inputSize = pixelSize * srcCols() * srcRows();

int outputSize = width * height * pixelSize;
size_t outputSize = width * height * pixelSize;
void * outputData = malloc( outputSize );

// Check for allcoation error
if ( ! outputData )
{
QgsDebugMsg( QString( "Couldn't malloc %1 bytes!" ).arg( outputSize ) );
free( inputData );
return 0;
}
// TODO: fill by transparent

int srcRow, srcCol;
@@ -694,8 +702,8 @@ void * QgsRasterProjector::readBlock( int bandNo, QgsRectangle const & extent,
for ( int j = 0; j < width; ++j )
{
srcRowCol( i, j, &srcRow, &srcCol );
int srcIndex = pixelSize * ( srcRow * mSrcCols + srcCol );
int destIndex = pixelSize * ( i * width + j );
size_t srcIndex = pixelSize * ( srcRow * mSrcCols + srcCol );
size_t destIndex = pixelSize * ( i * width + j );

if ( srcIndex >= inputSize || destIndex >= outputSize ) continue; // should not happen

@@ -195,7 +195,17 @@ void * QgsMultiBandColorRenderer::readBlock( int bandNo, QgsRectangle const & e
for ( ; bandIt != bands.constEnd(); ++bandIt )
{
bandData[*bandIt] = mInput->block( *bandIt, extent, width, height );
if ( !bandData[*bandIt] ) return 0;
if ( !bandData[*bandIt] )
{
// We should free the alloced mem from block().
QgsDebugMsg("No input band" );
bandIt--;
for ( ; bandIt != bands.constBegin(); bandIt-- )
{
VSIFree( bandData[*bandIt] );
}
return 0;
}
}

if ( mRedBand > 0 )
@@ -216,6 +226,17 @@ void * QgsMultiBandColorRenderer::readBlock( int bandNo, QgsRectangle const & e
}

QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
if ( img.isNull() )
{
QgsDebugMsg( "Could not create QImage" );
bandIt = bands.constBegin();
for ( ; bandIt != bands.constEnd(); ++bandIt )
{
VSIFree( bandData[*bandIt] );
}
return 0;
}

QRgb* imageScanLine = 0;
int currentRasterPos = 0;
int redVal = 0;
@@ -334,6 +355,11 @@ void * QgsMultiBandColorRenderer::readBlock( int bandNo, QgsRectangle const & e
}

void * data = VSIMalloc( img.byteCount() );
if ( ! data )
{
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
return 0;
}
return memcpy( data, img.bits(), img.byteCount() );
}

@@ -103,6 +103,12 @@ void * QgsPalettedRasterRenderer::readBlock( int bandNo, QgsRectangle const & e

QgsRasterInterface::DataType rasterType = ( QgsRasterInterface::DataType )mInput->dataType( mBandNumber );
void* rasterData = mInput->block( bandNo, extent, width, height );
if ( ! rasterData )
{
QgsDebugMsg("No raster data!" );
return 0;
}

double currentOpacity = mOpacity;

//rendering is faster without considering user-defined transparency
@@ -120,6 +126,13 @@ void * QgsPalettedRasterRenderer::readBlock( int bandNo, QgsRectangle const & e

//create image
QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
if ( img.isNull() )
{
QgsDebugMsg( "Could not create QImage" );
VSIFree( rasterData );
return 0;
}

QRgb* imageScanLine = 0;
int val = 0;
int currentRasterPos = 0;
@@ -174,7 +187,13 @@ void * QgsPalettedRasterRenderer::readBlock( int bandNo, QgsRectangle const & e
}

VSIFree( rasterData );

void * data = VSIMalloc( img.byteCount() );
if ( ! data )
{
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
return 0;
}
return memcpy( data, img.bits(), img.byteCount() );
}

@@ -62,9 +62,21 @@ void * QgsSingleBandColorDataRenderer::readBlock( int bandNo, QgsRectangle cons
bool hasTransparency = usesTransparency();

void* rasterData = mInput->block( bandNo, extent, width, height );
if ( ! rasterData )
{
QgsDebugMsg("No raster data!" );
return 0;
}

currentRasterPos = 0;
QImage img( width, height, QImage::Format_ARGB32 );
if ( img.isNull() )
{
QgsDebugMsg( "Could not create QImage" );
VSIFree( rasterData );
return 0;
}

uchar* scanLine = 0;
for ( int i = 0; i < height; ++i )
{
@@ -91,6 +103,11 @@ void * QgsSingleBandColorDataRenderer::readBlock( int bandNo, QgsRectangle cons
VSIFree( rasterData );

void * data = VSIMalloc( img.byteCount() );
if ( ! data )
{
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
return 0;
}
return memcpy( data, img.bits(), img.byteCount() );
}

@@ -89,6 +89,11 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co
QgsRasterInterface::DataType rasterType = ( QgsRasterInterface::DataType )mInput->dataType( mBand );

void* rasterData = mInput->block( mBand, extent, width, height );
if ( ! rasterData )
{
QgsDebugMsg("No raster data!" );
return 0;
}

int red, green, blue;
QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );
@@ -107,6 +112,13 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co

//create image
QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
if ( img.isNull() )
{
QgsDebugMsg( "Could not create QImage" );
VSIFree( rasterData );
return 0;
}

QRgb* imageScanLine = 0;
double val = 0;

@@ -156,6 +168,11 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co
VSIFree( rasterData );

void * data = VSIMalloc( img.byteCount() );
if ( ! data )
{
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
return 0;
}
return memcpy( data, img.bits(), img.byteCount() );
}

@@ -520,7 +520,11 @@ void QgsGdalProvider::readBlock( int theBandNo, QgsRectangle const & theExtent,

// Allocate temporary block
char *tmpBlock = ( char * )malloc( dataSize * tmpWidth * tmpHeight );

if ( ! tmpBlock )
{
QgsDebugMsg( QString( "Coudn't allocate temporary buffer of %1 bytes" ).arg( dataSize * tmpWidth * tmpHeight ) );
return;
}
GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
GDALDataType type = ( GDALDataType )mGdalDataType[theBandNo-1];
CPLErrorReset();
@@ -537,6 +537,11 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
QgsDebugMsg( QString( "pixelSize = %1" ).arg( pixelSize ) );
int size = width * height * pixelSize;
void * tmpData = malloc( size );
if ( ! tmpData )
{
QgsDebugMsg( QString( "Couldn't allocate memory of %1 bytes" ).arg( size ) );
return;
}
GDALRasterIO( gdalBand, GF_Read, 0, 0, width, height, tmpData, width, height, ( GDALDataType ) mGdalDataType[bandNo-1], 0, 0 );
for ( int i = 0; i < pixelHeight; i++ )
{
@@ -959,16 +959,20 @@ void QgsWmsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
return;
}
QgsDebugMsg( QString( "image height = %1 bytesPerLine = %2" ).arg( image->height() ) . arg( image->bytesPerLine() ) ) ;
int myExpectedSize = pixelWidth * pixelHeight * 4;
int myImageSize = image->height() * image->bytesPerLine();
size_t myExpectedSize = pixelWidth * pixelHeight * 4;
size_t myImageSize = image->height() * image->bytesPerLine();
if ( myExpectedSize != myImageSize ) // should not happen
{
QgsMessageLog::logMessage( tr( "unexpected image size" ), tr( "WMS" ) );
return;
}

uchar * ptr = image->bits() ;
memcpy( block, ptr, myExpectedSize );
if ( ptr )
{
// If image is too large, ptr can be NULL
memcpy( block, ptr, myExpectedSize );
}
// do not delete the image, it is handled by draw()
//delete image;
}

0 comments on commit d11fd92

Please sign in to comment.
You can’t perform that action at this time.