Skip to content

Commit 000f689

Browse files
committed
#6504 fix - raster reprojection crash
1 parent 2754df0 commit 000f689

File tree

3 files changed

+102
-90
lines changed

3 files changed

+102
-90
lines changed

src/core/raster/qgsrasterblock.cpp

Lines changed: 84 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -27,41 +27,41 @@
2727
#include "cpl_conv.h"
2828

2929
QgsRasterBlock::QgsRasterBlock()
30-
//mValid (false)
31-
: mDataType ( UnknownDataType )
32-
, mTypeSize(0)
33-
, mWidth(0)
34-
, mHeight(0)
35-
, mNoDataValue(std::numeric_limits<double>::quiet_NaN())
36-
, mData(0)
37-
, mImage(0)
30+
//mValid (false)
31+
: mDataType( UnknownDataType )
32+
, mTypeSize( 0 )
33+
, mWidth( 0 )
34+
, mHeight( 0 )
35+
, mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
36+
, mData( 0 )
37+
, mImage( 0 )
3838
{
3939
}
4040

4141
QgsRasterBlock::QgsRasterBlock( DataType theDataType, int theWidth, int theHeight, double theNoDataValue )
42-
//mValid(true)
43-
: mDataType(theDataType)
44-
, mTypeSize(0)
45-
, mWidth(theWidth)
46-
, mHeight(theHeight)
47-
, mNoDataValue(theNoDataValue)
48-
, mData(0)
49-
, mImage(0)
42+
//mValid(true)
43+
: mDataType( theDataType )
44+
, mTypeSize( 0 )
45+
, mWidth( theWidth )
46+
, mHeight( theHeight )
47+
, mNoDataValue( theNoDataValue )
48+
, mData( 0 )
49+
, mImage( 0 )
5050
{
51-
reset ( mDataType, mWidth, mHeight, mNoDataValue );
51+
reset( mDataType, mWidth, mHeight, mNoDataValue );
5252
}
5353

5454
QgsRasterBlock::~QgsRasterBlock()
5555
{
56-
QgsFree(mData);
57-
56+
QgsFree( mData );
57+
5858
}
5959

6060
bool QgsRasterBlock::reset( DataType theDataType, int theWidth, int theHeight, double theNoDataValue )
6161
{
62-
QgsDebugMsg ( QString("theWidth= %1 theHeight = %2 theDataType = %3 theNoDataValue = %4").arg(theWidth).arg(theHeight).arg(theDataType).arg(theNoDataValue));
62+
QgsDebugMsg( QString( "theWidth= %1 theHeight = %2 theDataType = %3 theNoDataValue = %4" ).arg( theWidth ).arg( theHeight ).arg( theDataType ).arg( theNoDataValue ) );
6363

64-
QgsFree(mData);
64+
QgsFree( mData );
6565
mData = 0;
6666
delete mImage;
6767
mImage = 0;
@@ -72,9 +72,9 @@ bool QgsRasterBlock::reset( DataType theDataType, int theWidth, int theHeight, d
7272
mNoDataValue = std::numeric_limits<double>::quiet_NaN();
7373
//mValid = false;
7474

75-
if ( typeIsNumeric(theDataType) )
75+
if ( typeIsNumeric( theDataType ) )
7676
{
77-
QgsDebugMsg ( "Numeric type");
77+
QgsDebugMsg( "Numeric type" );
7878
int tSize = typeSize( theDataType ) / 8;
7979
mData = QgsMalloc( tSize * theWidth * theHeight );
8080
if ( mData == 0 )
@@ -85,23 +85,23 @@ bool QgsRasterBlock::reset( DataType theDataType, int theWidth, int theHeight, d
8585
}
8686
else if ( typeIsColor( theDataType ) )
8787
{
88-
QgsDebugMsg ( "Color type");
89-
QImage::Format format = imageFormat ( theDataType );
88+
QgsDebugMsg( "Color type" );
89+
QImage::Format format = imageFormat( theDataType );
9090
mImage = new QImage( theWidth, theHeight, format );
9191
}
9292
else
9393
{
94-
QgsDebugMsg ( "Wrong data type");
94+
QgsDebugMsg( "Wrong data type" );
9595
return false;
9696
}
97-
97+
9898
//mValid = true;
9999
mDataType = theDataType;
100-
mTypeSize = QgsRasterBlock::typeSize(mDataType);
100+
mTypeSize = QgsRasterBlock::typeSize( mDataType );
101101
mWidth = theWidth;
102102
mHeight = theHeight;
103103
mNoDataValue = theNoDataValue;
104-
QgsDebugMsg ( QString("mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5").arg(mWidth).arg(mHeight).arg(mDataType).arg((ulong)mData).arg((ulong)mImage));
104+
QgsDebugMsg( QString( "mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5" ).arg( mWidth ).arg( mHeight ).arg( mDataType ).arg(( ulong )mData ).arg(( ulong )mImage ) );
105105
return true;
106106
}
107107

@@ -112,15 +112,15 @@ QImage::Format QgsRasterBlock::imageFormat( QgsRasterBlock::DataType theDataType
112112
return QImage::Format_ARGB32;
113113
}
114114
else if ( theDataType == QgsRasterBlock::ARGB32_Premultiplied )
115-
{
115+
{
116116
return QImage::Format_ARGB32_Premultiplied;
117117
}
118118
return QImage::Format_Invalid;
119119
}
120120

121-
QgsRasterBlock::DataType QgsRasterBlock::dataType ( QImage::Format theFormat )
121+
QgsRasterBlock::DataType QgsRasterBlock::dataType( QImage::Format theFormat )
122122
{
123-
if ( theFormat == QImage::Format_ARGB32 )
123+
if ( theFormat == QImage::Format_ARGB32 )
124124
{
125125
return QgsRasterBlock::ARGB32;
126126
}
@@ -133,9 +133,9 @@ QgsRasterBlock::DataType QgsRasterBlock::dataType ( QImage::Format theFormat )
133133

134134
bool QgsRasterBlock::isEmpty() const
135135
{
136-
QgsDebugMsg ( QString("mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5").arg(mWidth).arg(mHeight).arg(mDataType).arg((ulong)mData).arg((ulong)mImage));
137-
if ( mWidth == 0 || mHeight == 0 ||
138-
( typeIsNumeric(mDataType ) && mData == 0 ) ||
136+
QgsDebugMsg( QString( "mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5" ).arg( mWidth ).arg( mHeight ).arg( mDataType ).arg(( ulong )mData ).arg(( ulong )mImage ) );
137+
if ( mWidth == 0 || mHeight == 0 ||
138+
( typeIsNumeric( mDataType ) && mData == 0 ) ||
139139
( typeIsColor( mDataType ) && mImage == 0 ) )
140140
{
141141
return true;
@@ -250,147 +250,153 @@ bool QgsRasterBlock::isNoDataValue( double value ) const
250250
return false;
251251
}
252252

253-
double QgsRasterBlock::value( size_t index) const
253+
double QgsRasterBlock::value( size_t index ) const
254254
{
255-
if ( index < 0 || index >= (size_t)mWidth*mHeight )
255+
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
256256
{
257-
QgsDebugMsg( QString("Index %1 out of range (%2 x %3)").arg(index).arg(mWidth).arg(mHeight) );
257+
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
258258
return mNoDataValue;
259259
}
260-
return readValue ( mData, mDataType, index );
260+
return readValue( mData, mDataType, index );
261261
}
262262

263-
double QgsRasterBlock::value( int row, int column) const
263+
double QgsRasterBlock::value( int row, int column ) const
264264
{
265-
return value ( (size_t)row*mWidth+column);
265+
return value(( size_t )row*mWidth + column );
266266
}
267267

268-
QRgb QgsRasterBlock::color( size_t index) const
268+
QRgb QgsRasterBlock::color( size_t index ) const
269269
{
270-
int row = floor ( (double)index / mWidth );
270+
int row = floor(( double )index / mWidth );
271271
int column = index % mWidth;
272-
return color( row, column);
272+
return color( row, column );
273273
}
274274

275-
QRgb QgsRasterBlock::color( int row, int column) const
275+
QRgb QgsRasterBlock::color( int row, int column ) const
276276
{
277277
if ( !mImage ) return qRgba( 255, 255, 255, 0 );
278278

279-
return mImage->pixel ( column, row );
279+
return mImage->pixel( column, row );
280280
}
281281

282282
bool QgsRasterBlock::isNoData( size_t index )
283283
{
284-
if ( index < 0 || index >= (size_t)mWidth*mHeight )
284+
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
285285
{
286-
QgsDebugMsg( QString("Index %1 out of range (%2 x %3)").arg(index).arg(mWidth).arg(mHeight) );
286+
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
287287
return true; // we consider no data if outside
288288
}
289-
double value = readValue ( mData, mDataType, index );
289+
double value = readValue( mData, mDataType, index );
290290
return isNoDataValue( value );
291291
}
292292

293293
bool QgsRasterBlock::isNoData( int row, int column )
294294
{
295-
return isNoData( (size_t)row*mWidth+column );
295+
return isNoData(( size_t )row*mWidth + column );
296296
}
297297

298298
bool QgsRasterBlock::setValue( size_t index, double value )
299299
{
300-
if ( !mData )
300+
if ( !mData )
301301
{
302302
QgsDebugMsg( "Data block not allocated" );
303303
return false;
304304
}
305-
if ( index < 0 || index >= (size_t)mWidth*mHeight )
305+
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
306306
{
307-
QgsDebugMsg( QString("Index %1 out of range (%2 x %3)").arg(index).arg(mWidth).arg(mHeight) );
307+
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
308308
return false;
309309
}
310-
writeValue ( mData, mDataType, index, value );
310+
writeValue( mData, mDataType, index, value );
311311
return true;
312312
}
313313

314314
bool QgsRasterBlock::setValue( int row, int column, double value )
315315
{
316-
return setValue ( (size_t)row*mWidth+column, value );
316+
return setValue(( size_t )row*mWidth + column, value );
317317
}
318318

319319
bool QgsRasterBlock::setColor( int row, int column, QRgb color )
320320
{
321-
return setColor( (size_t)row*column, color );
321+
return setColor(( size_t )row*column, color );
322322
}
323323

324324
bool QgsRasterBlock::setColor( size_t index, QRgb color )
325325
{
326-
if ( !mImage )
326+
if ( !mImage )
327327
{
328328
QgsDebugMsg( "Image not allocated" );
329329
return false;
330330
}
331331

332-
if ( index >= (size_t)mImage->width()* mImage->height() )
332+
if ( index >= ( size_t )mImage->width()* mImage->height() )
333333
{
334-
QgsDebugMsg( QString("index %1 out of range").arg(index) );
334+
QgsDebugMsg( QString( "index %1 out of range" ).arg( index ) );
335335
return false;
336336
}
337-
337+
338338
// setPixel() is slow, see Qt doc -> use direct access
339-
QRgb* bits = (QRgb*)mImage->bits();
339+
QRgb* bits = ( QRgb* )mImage->bits();
340340
bits[index] = color;
341341
return true;
342342
}
343343

344344
char * QgsRasterBlock::bits( size_t index )
345345
{
346-
if ( mData )
346+
// Not testing type to avoid too much overhead because this method is called per pixel
347+
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
347348
{
348-
return (char*)mData + index * mTypeSize;
349+
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
350+
return 0;
349351
}
350-
if ( mImage )
352+
if ( mData )
351353
{
352-
return (char*) (mImage->bits() + index * 4);
354+
return ( char* )mData + index * mTypeSize;
355+
}
356+
if ( mImage && mImage->bits() )
357+
{
358+
return ( char* )( mImage->bits() + index * 4 );
353359
}
354360

355361
return 0;
356362
}
357363

358364
char * QgsRasterBlock::bits( int row, int column )
359365
{
360-
return bits ( (size_t)row*mWidth + column );
366+
return bits(( size_t )row*mWidth + column );
361367
}
362368

363369
bool QgsRasterBlock::convert( QgsRasterBlock::DataType destDataType )
364370
{
365371
if ( isEmpty() ) return false;
366372
if ( destDataType == mDataType ) return true;
367373

368-
if ( typeIsNumeric(mDataType) && typeIsNumeric(destDataType) )
374+
if ( typeIsNumeric( mDataType ) && typeIsNumeric( destDataType ) )
369375
{
370-
void *data = convert ( mData, mDataType, destDataType, mWidth*mHeight );
376+
void *data = convert( mData, mDataType, destDataType, mWidth * mHeight );
371377

372378
if ( data == 0 )
373379
{
374-
QgsDebugMsg ( "Cannot convert raster block" );
380+
QgsDebugMsg( "Cannot convert raster block" );
375381
return false;
376382
}
377-
QgsFree ( mData );
383+
QgsFree( mData );
378384
mData = data;
379385
}
380-
else if ( typeIsColor(mDataType) && typeIsColor(destDataType) )
386+
else if ( typeIsColor( mDataType ) && typeIsColor( destDataType ) )
381387
{
382388
// It would be probably faster to convert value by value here instead of
383389
// creating new image, QImage (4.8) does not have any method to convert in place
384-
QImage::Format format = imageFormat ( destDataType );
385-
QImage image = mImage->convertToFormat ( format );
386-
memcpy ( mImage->bits(), image.bits(), mImage->byteCount() );
390+
QImage::Format format = imageFormat( destDataType );
391+
QImage image = mImage->convertToFormat( format );
392+
memcpy( mImage->bits(), image.bits(), mImage->byteCount() );
387393
//mImage = new QImage( mWidth, mHeight, format );
388394
}
389395
else
390396
{
391397
return false;
392398
}
393-
399+
394400
return true;
395401
}
396402

@@ -409,11 +415,11 @@ bool QgsRasterBlock::setImage( const QImage * image )
409415
mData = 0;
410416
delete mImage;
411417
mImage = 0;
412-
mImage = new QImage ( *image );
418+
mImage = new QImage( *image );
413419
mWidth = mImage->width();
414420
mHeight = mImage->height();
415-
mDataType = dataType ( mImage->format() );
416-
mTypeSize = QgsRasterBlock::typeSize(mDataType);
421+
mDataType = dataType( mImage->format() );
422+
mTypeSize = QgsRasterBlock::typeSize( mDataType );
417423
mNoDataValue = std::numeric_limits<double>::quiet_NaN();
418424
return true;
419425
}

src/core/raster/qgsrasterdrawer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ void QgsRasterDrawer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsM
6363
while ( mIterator->readNextRasterPart( bandNumber, nCols, nRows,
6464
&block, topLeftCol, topLeftRow ) )
6565
{
66+
if ( !block )
67+
{
68+
QgsDebugMsg( "Cannot get block" );
69+
continue;
70+
}
6671
//create image
6772
//QImage img( nRasterCols, nRasterRows, QImage::Format_ARGB32_Premultiplied );
6873

0 commit comments

Comments
 (0)