Skip to content

Commit d11fd92

Browse files
committed
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.
2 parents 24a047d + e2e2792 commit d11fd92

9 files changed

Lines changed: 119 additions & 14 deletions

‎src/core/qgsrasterdataprovider.cpp‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ void QgsRasterDataProvider::readBlock( int bandNo, QgsRectangle
6464
return;
6565

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

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

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

106111
return data;
@@ -260,9 +265,9 @@ QString QgsRasterDataProvider::lastErrorFormat()
260265
QByteArray QgsRasterDataProvider::noValueBytes( int theBandNo )
261266
{
262267
int type = dataType( theBandNo );
263-
int size = dataTypeSize( theBandNo ) / 8;
268+
size_t size = dataTypeSize( theBandNo ) / 8;
264269
QByteArray ba;
265-
ba.resize( size );
270+
ba.resize(( int )size );
266271
char * data = ba.data();
267272
double noval = mNoDataValue[theBandNo-1];
268273
unsigned char uc;

‎src/core/qgsrasterprojector.cpp‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ QgsRasterProjector::QgsRasterProjector()
6767
}
6868

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

680681
if ( !inputData ) return 0;
681682

682-
int pixelSize = mInput->typeSize( mInput->dataType( bandNo ) ) / 8;
683+
size_t pixelSize = mInput->typeSize( mInput->dataType( bandNo ) ) / 8;
683684

684-
int inputSize = pixelSize * srcCols() * srcRows();
685+
size_t inputSize = pixelSize * srcCols() * srcRows();
685686

686-
int outputSize = width * height * pixelSize;
687+
size_t outputSize = width * height * pixelSize;
687688
void * outputData = malloc( outputSize );
688689

690+
// Check for allcoation error
691+
if ( ! outputData )
692+
{
693+
QgsDebugMsg( QString( "Couldn't malloc %1 bytes!" ).arg( outputSize ) );
694+
free( inputData );
695+
return 0;
696+
}
689697
// TODO: fill by transparent
690698

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

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

‎src/core/raster/qgsmultibandcolorrenderer.cpp‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,17 @@ void * QgsMultiBandColorRenderer::readBlock( int bandNo, QgsRectangle const & e
195195
for ( ; bandIt != bands.constEnd(); ++bandIt )
196196
{
197197
bandData[*bandIt] = mInput->block( *bandIt, extent, width, height );
198-
if ( !bandData[*bandIt] ) return 0;
198+
if ( !bandData[*bandIt] )
199+
{
200+
// We should free the alloced mem from block().
201+
QgsDebugMsg("No input band" );
202+
bandIt--;
203+
for ( ; bandIt != bands.constBegin(); bandIt-- )
204+
{
205+
VSIFree( bandData[*bandIt] );
206+
}
207+
return 0;
208+
}
199209
}
200210

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

218228
QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
229+
if ( img.isNull() )
230+
{
231+
QgsDebugMsg( "Could not create QImage" );
232+
bandIt = bands.constBegin();
233+
for ( ; bandIt != bands.constEnd(); ++bandIt )
234+
{
235+
VSIFree( bandData[*bandIt] );
236+
}
237+
return 0;
238+
}
239+
219240
QRgb* imageScanLine = 0;
220241
int currentRasterPos = 0;
221242
int redVal = 0;
@@ -334,6 +355,11 @@ void * QgsMultiBandColorRenderer::readBlock( int bandNo, QgsRectangle const & e
334355
}
335356

336357
void * data = VSIMalloc( img.byteCount() );
358+
if ( ! data )
359+
{
360+
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
361+
return 0;
362+
}
337363
return memcpy( data, img.bits(), img.byteCount() );
338364
}
339365

‎src/core/raster/qgspalettedrasterrenderer.cpp‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ void * QgsPalettedRasterRenderer::readBlock( int bandNo, QgsRectangle const & e
103103

104104
QgsRasterInterface::DataType rasterType = ( QgsRasterInterface::DataType )mInput->dataType( mBandNumber );
105105
void* rasterData = mInput->block( bandNo, extent, width, height );
106+
if ( ! rasterData )
107+
{
108+
QgsDebugMsg("No raster data!" );
109+
return 0;
110+
}
111+
106112
double currentOpacity = mOpacity;
107113

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

121127
//create image
122128
QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
129+
if ( img.isNull() )
130+
{
131+
QgsDebugMsg( "Could not create QImage" );
132+
VSIFree( rasterData );
133+
return 0;
134+
}
135+
123136
QRgb* imageScanLine = 0;
124137
int val = 0;
125138
int currentRasterPos = 0;
@@ -174,7 +187,13 @@ void * QgsPalettedRasterRenderer::readBlock( int bandNo, QgsRectangle const & e
174187
}
175188

176189
VSIFree( rasterData );
190+
177191
void * data = VSIMalloc( img.byteCount() );
192+
if ( ! data )
193+
{
194+
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
195+
return 0;
196+
}
178197
return memcpy( data, img.bits(), img.byteCount() );
179198
}
180199

‎src/core/raster/qgssinglebandcolordatarenderer.cpp‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,21 @@ void * QgsSingleBandColorDataRenderer::readBlock( int bandNo, QgsRectangle cons
6262
bool hasTransparency = usesTransparency();
6363

6464
void* rasterData = mInput->block( bandNo, extent, width, height );
65+
if ( ! rasterData )
66+
{
67+
QgsDebugMsg("No raster data!" );
68+
return 0;
69+
}
6570

6671
currentRasterPos = 0;
6772
QImage img( width, height, QImage::Format_ARGB32 );
73+
if ( img.isNull() )
74+
{
75+
QgsDebugMsg( "Could not create QImage" );
76+
VSIFree( rasterData );
77+
return 0;
78+
}
79+
6880
uchar* scanLine = 0;
6981
for ( int i = 0; i < height; ++i )
7082
{
@@ -91,6 +103,11 @@ void * QgsSingleBandColorDataRenderer::readBlock( int bandNo, QgsRectangle cons
91103
VSIFree( rasterData );
92104

93105
void * data = VSIMalloc( img.byteCount() );
106+
if ( ! data )
107+
{
108+
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
109+
return 0;
110+
}
94111
return memcpy( data, img.bits(), img.byteCount() );
95112
}
96113

‎src/core/raster/qgssinglebandpseudocolorrenderer.cpp‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co
8989
QgsRasterInterface::DataType rasterType = ( QgsRasterInterface::DataType )mInput->dataType( mBand );
9090

9191
void* rasterData = mInput->block( mBand, extent, width, height );
92+
if ( ! rasterData )
93+
{
94+
QgsDebugMsg("No raster data!" );
95+
return 0;
96+
}
9297

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

108113
//create image
109114
QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
115+
if ( img.isNull() )
116+
{
117+
QgsDebugMsg( "Could not create QImage" );
118+
VSIFree( rasterData );
119+
return 0;
120+
}
121+
110122
QRgb* imageScanLine = 0;
111123
double val = 0;
112124

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

158170
void * data = VSIMalloc( img.byteCount() );
171+
if ( ! data )
172+
{
173+
QgsDebugMsg( QString( "Couldn't allocate output data memory of % bytes" ).arg( img.byteCount() ) );
174+
return 0;
175+
}
159176
return memcpy( data, img.bits(), img.byteCount() );
160177
}
161178

‎src/providers/gdal/qgsgdalprovider.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,11 @@ void QgsGdalProvider::readBlock( int theBandNo, QgsRectangle const & theExtent,
520520

521521
// Allocate temporary block
522522
char *tmpBlock = ( char * )malloc( dataSize * tmpWidth * tmpHeight );
523-
523+
if ( ! tmpBlock )
524+
{
525+
QgsDebugMsg( QString( "Coudn't allocate temporary buffer of %1 bytes" ).arg( dataSize * tmpWidth * tmpHeight ) );
526+
return;
527+
}
524528
GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
525529
GDALDataType type = ( GDALDataType )mGdalDataType[theBandNo-1];
526530
CPLErrorReset();

‎src/providers/wcs/qgswcsprovider.cpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,11 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
537537
QgsDebugMsg( QString( "pixelSize = %1" ).arg( pixelSize ) );
538538
int size = width * height * pixelSize;
539539
void * tmpData = malloc( size );
540+
if ( ! tmpData )
541+
{
542+
QgsDebugMsg( QString( "Couldn't allocate memory of %1 bytes" ).arg( size ) );
543+
return;
544+
}
540545
GDALRasterIO( gdalBand, GF_Read, 0, 0, width, height, tmpData, width, height, ( GDALDataType ) mGdalDataType[bandNo-1], 0, 0 );
541546
for ( int i = 0; i < pixelHeight; i++ )
542547
{

‎src/providers/wms/qgswmsprovider.cpp‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -959,16 +959,20 @@ void QgsWmsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in
959959
return;
960960
}
961961
QgsDebugMsg( QString( "image height = %1 bytesPerLine = %2" ).arg( image->height() ) . arg( image->bytesPerLine() ) ) ;
962-
int myExpectedSize = pixelWidth * pixelHeight * 4;
963-
int myImageSize = image->height() * image->bytesPerLine();
962+
size_t myExpectedSize = pixelWidth * pixelHeight * 4;
963+
size_t myImageSize = image->height() * image->bytesPerLine();
964964
if ( myExpectedSize != myImageSize ) // should not happen
965965
{
966966
QgsMessageLog::logMessage( tr( "unexpected image size" ), tr( "WMS" ) );
967967
return;
968968
}
969969

970970
uchar * ptr = image->bits() ;
971-
memcpy( block, ptr, myExpectedSize );
971+
if ( ptr )
972+
{
973+
// If image is too large, ptr can be NULL
974+
memcpy( block, ptr, myExpectedSize );
975+
}
972976
// do not delete the image, it is handled by draw()
973977
//delete image;
974978
}

0 commit comments

Comments
 (0)