27 const QRgb QgsRasterBlock::mNoDataColor = qRgba( 0, 0, 0, 0 );
31 , mDataType(
QGis::UnknownDataType )
35 , mHasNoDataValue( false )
36 , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
40 , mNoDataBitmapWidth( 0 )
41 , mNoDataBitmapSize( 0 )
47 , mDataType( theDataType )
50 , mHeight( theHeight )
51 , mHasNoDataValue( false )
52 , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
56 , mNoDataBitmapWidth( 0 )
57 , mNoDataBitmapSize( 0 )
59 ( void )
reset( mDataType, mWidth, mHeight );
64 , mDataType( theDataType )
67 , mHeight( theHeight )
68 , mHasNoDataValue( true )
69 , mNoDataValue( theNoDataValue )
73 , mNoDataBitmapWidth( 0 )
74 , mNoDataBitmapSize( 0 )
76 ( void )
reset( mDataType, mWidth, mHeight, mNoDataValue );
81 QgsDebugMsg( QString(
"mData = %1" ).arg(( ulong )mData ) );
89 QgsDebugMsg( QString(
"theWidth= %1 theHeight = %2 theDataType = %3" ).arg( theWidth ).arg( theHeight ).arg( theDataType ) );
90 if ( !
reset( theDataType, theWidth, theHeight, std::numeric_limits<double>::quiet_NaN() ) )
94 mHasNoDataValue =
false;
101 QgsDebugMsg( QString(
"theWidth= %1 theHeight = %2 theDataType = %3 theNoDataValue = %4" ).arg( theWidth ).arg( theHeight ).arg( theDataType ).arg( theNoDataValue ) );
113 mHasNoDataValue =
false;
114 mNoDataValue = std::numeric_limits<double>::quiet_NaN();
121 QgsDebugMsg( QString(
"allocate %1 bytes" ).arg( tSize * theWidth * theHeight ) );
122 mData =
qgsMalloc( tSize * theWidth * theHeight );
125 QgsDebugMsg( QString(
"Couldn't allocate data memory of %1 bytes" ).arg( tSize * theWidth * theHeight ) );
132 QImage::Format format = imageFormat( theDataType );
133 mImage =
new QImage( theWidth, theHeight, format );
142 mDataType = theDataType;
146 mHasNoDataValue =
true;
147 mNoDataValue = theNoDataValue;
148 QgsDebugMsg( QString(
"mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5" ).arg( mWidth ).arg( mHeight ).arg( mDataType ).arg(( ulong )mData ).arg(( ulong )mImage ) );
152 QImage::Format QgsRasterBlock::imageFormat(
QGis::DataType theDataType )
156 return QImage::Format_ARGB32;
160 return QImage::Format_ARGB32_Premultiplied;
162 return QImage::Format_Invalid;
167 if ( theFormat == QImage::Format_ARGB32 )
171 else if ( theFormat == QImage::Format_ARGB32_Premultiplied )
180 QgsDebugMsg( QString(
"mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5" ).arg( mWidth ).arg( mHeight ).arg( mDataType ).arg(( ulong )mData ).arg(( ulong )mImage ) );
181 if ( mWidth == 0 || mHeight == 0 ||
247 *noDataValue = -32768.0;
251 *noDataValue = -2147483648.0;
255 *noDataValue = -2147483648.0;
266 QgsDebugMsg( QString(
"Unknow data type %1" ).arg( dataType ) );
270 QgsDebugMsg( QString(
"newDataType = %1 noDataValue = %2" ).arg( newDataType ).arg( *noDataValue ) );
276 return mHasNoDataValue || mNoDataBitmap != 0;
279 bool QgsRasterBlock::isNoDataValue(
double value,
double noDataValue )
284 if ( qIsNaN( value ) ||
299 int row = floor((
double )index / mWidth );
300 int column = index % mWidth;
301 return color( row, column );
306 if ( !mImage )
return mNoDataColor;
308 return mImage->pixel( column, row );
313 if ( !mHasNoDataValue && !mNoDataBitmap )
return false;
314 if ( index >= (
qgssize )mWidth*mHeight )
316 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
319 if ( mHasNoDataValue )
321 double value =
readValue( mData, mDataType, index );
322 return isNoDataValue( value );
325 if ( mNoDataBitmap == 0 )
331 int row = ( int ) index / mWidth;
332 int column = index % mWidth;
334 int bit = column % 8;
335 int mask = 0x80 >> bit;
338 return mNoDataBitmap[byte] & mask;
353 if ( index >= (
qgssize )mWidth*mHeight )
355 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
380 if ( index >= (
qgssize )mImage->width()* mImage->height() )
382 QgsDebugMsg( QString(
"index %1 out of range" ).arg( index ) );
387 QRgb*
bits = ( QRgb* )mImage->bits();
399 if ( mHasNoDataValue )
401 return setValue( index, mNoDataValue );
405 if ( mNoDataBitmap == 0 )
407 if ( !createNoDataBitmap() )
413 int row = ( int ) index / mWidth;
414 int column = index % mWidth;
416 int bit = column % 8;
417 int nodata = 0x80 >> bit;
419 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
429 if ( mHasNoDataValue )
439 QByteArray noDataByteArray =
valueBytes( mDataType, mNoDataValue );
441 char *nodata = noDataByteArray.data();
444 memcpy((
char* )mData + i*dataTypeSize, nodata, dataTypeSize );
450 if ( mNoDataBitmap == 0 )
452 if ( !createNoDataBitmap() )
458 memset( mNoDataBitmap, 0xff, mNoDataBitmapSize );
471 mImage->fill( mNoDataColor );
478 int top = theExceptRect.top();
479 int bottom = theExceptRect.bottom();
480 int left = theExceptRect.left();
481 int right = theExceptRect.right();
482 top = qMin( qMax( top, 0 ), mHeight - 1 );
483 left = qMin( qMax( left, 0 ), mWidth - 1 );
484 bottom = qMax( 0, qMin( bottom, mHeight - 1 ) );
485 right = qMax( 0, qMin( right, mWidth - 1 ) );
490 if ( mHasNoDataValue )
500 QByteArray noDataByteArray =
valueBytes( mDataType, mNoDataValue );
502 char *nodata = noDataByteArray.data();
504 for (
int c = 0; c < mWidth; c++ )
506 memcpy( nodataRow + c*dataTypeSize, nodata, dataTypeSize );
510 for (
int r = 0; r < mHeight; r++ )
512 if ( r >= top && r <= bottom )
continue;
514 memcpy((
char* )mData + i*dataTypeSize, nodataRow, dataTypeSize*mWidth );
517 for (
int r = top; r <= bottom; r++ )
521 memcpy((
char* )mData + i*dataTypeSize, nodataRow, dataTypeSize*left );
524 int w = mWidth - right - 1;
525 memcpy((
char* )mData + i*dataTypeSize, nodataRow, dataTypeSize*w );
532 if ( mNoDataBitmap == 0 )
534 if ( !createNoDataBitmap() )
541 char *nodataRow =
new char[mNoDataBitmapWidth];
543 memset( nodataRow, 0, mNoDataBitmapWidth );
544 for (
int c = 0; c < mWidth; c ++ )
548 char nodata = 0x80 >> bit;
549 memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
553 for (
int r = 0; r < mHeight; r++ )
555 if ( r >= top && r <= bottom )
continue;
557 memcpy( mNoDataBitmap + i, nodataRow, mNoDataBitmapWidth );
560 memset( nodataRow, 0, mNoDataBitmapWidth );
561 for (
int c = 0; c < mWidth; c ++ )
563 if ( c >= left && c <= right )
continue;
566 char nodata = 0x80 >> bit;
567 memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
569 for (
int r = top; r <= bottom; r++ )
572 memcpy( mNoDataBitmap + i, nodataRow, mNoDataBitmapWidth );
587 if ( mImage->width() != mWidth || mImage->height() != mHeight )
593 QgsDebugMsg( QString(
"Fill image depth = %1" ).arg( mImage->depth() ) );
596 if ( mImage->depth() != 32 )
602 QRgb nodataRgba = mNoDataColor;
603 QRgb *nodataRow =
new QRgb[mWidth];
604 int rgbSize =
sizeof( QRgb );
605 for (
int c = 0; c < mWidth; c ++ )
607 nodataRow[c] = nodataRgba;
611 for (
int r = 0; r < mHeight; r++ )
613 if ( r >= top && r <= bottom )
continue;
615 memcpy((
void * )( mImage->bits() + rgbSize*i ), nodataRow, rgbSize*mWidth );
618 for (
int r = top; r <= bottom; r++ )
624 memcpy((
void * )( mImage->bits() + rgbSize*i ), nodataRow, rgbSize*( left - 1 ) );
628 int w = mWidth - right - 1;
629 memcpy((
void * )( mImage->bits() + rgbSize*i ), nodataRow, rgbSize*w );
639 if ( index >= (
qgssize )mWidth*mHeight )
641 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
646 return (
char* )mData + index * mTypeSize;
648 if ( mImage && mImage->bits() )
650 return (
char* )( mImage->bits() + index * 4 );
665 return (
char* )mData;
667 if ( mImage && mImage->bits() )
669 return (
char* )( mImage->bits() );
678 if ( destDataType == mDataType )
return true;
691 mDataType = destDataType;
696 QImage::Format format = imageFormat( destDataType );
697 QImage
image = mImage->convertToFormat( format );
699 mDataType = destDataType;
714 if ( scale == 1.0 && offset == 0.0 )
return;
726 if ( rangeList.isEmpty() )
734 double val =
value( i );
747 return QImage( *mImage );
758 mImage =
new QImage( *image );
759 mWidth = mImage->width();
760 mHeight = mImage->height();
761 mDataType =
dataType( mImage->format() );
763 mNoDataValue = std::numeric_limits<double>::quiet_NaN();
793 for (
int i = 15; i <= 17; i++ )
795 s.setNum( value,
'g', i );
796 if ( s.toDouble() ==
value )
802 QgsDebugMsg(
"Cannot correctly parse printed value" );
808 int destDataTypeSize =
typeSize( destDataType );
809 void *destData =
qgsMalloc( destDataTypeSize * size );
812 double value =
readValue( srcData, srcDataType, i );
813 writeValue( destData, destDataType, i, value );
824 ba.resize((
int )size );
825 char * data = ba.data();
833 switch ( theDataType )
836 uc = ( quint8 )theValue;
837 memcpy( data, &uc, size );
840 us = ( quint16 )theValue;
841 memcpy( data, &us, size );
844 s = ( qint16 )theValue;
845 memcpy( data, &s, size );
848 ui = ( quint32 )theValue;
849 memcpy( data, &ui, size );
852 i = ( qint32 )theValue;
853 memcpy( data, &i, size );
856 f = ( float )theValue;
857 memcpy( data, &f, size );
860 d = ( double )theValue;
861 memcpy( data, &d, size );
869 bool QgsRasterBlock::createNoDataBitmap()
871 mNoDataBitmapWidth = mWidth / 8 + 1;
872 mNoDataBitmapSize = (
qgssize )mNoDataBitmapWidth * mHeight;
873 QgsDebugMsg( QString(
"allocate %1 bytes" ).arg( mNoDataBitmapSize ) );
874 mNoDataBitmap = (
char* )
qgsMalloc( mNoDataBitmapSize );
875 if ( mNoDataBitmap == 0 )
877 QgsDebugMsg( QString(
"Couldn't allocate no data memory of %1 bytes" ).arg( mNoDataBitmapSize ) );
880 memset( mNoDataBitmap, 0, mNoDataBitmapSize );
888 double xRes = theExtent.
width() / theWidth;
889 double yRes = theExtent.
height() / theHeight;
891 QgsDebugMsg( QString(
"theWidth = %1 theHeight = %2 xRes = %3 yRes = %4" ).arg( theWidth ).arg( theHeight ).arg( xRes ).arg( yRes ) );
894 int bottom = theHeight - 1;
896 int right = theWidth - 1;
904 bottom = qRound(( theExtent.
yMaximum() - theSubExtent.
yMinimum() ) / yRes ) - 1;
913 right = qRound(( theSubExtent.
xMaximum() - theExtent.
xMinimum() ) / xRes ) - 1;
915 QRect
subRect = QRect( left, top, right - left + 1, bottom - top + 1 );
916 QgsDebugMsg( QString(
"subRect: %1 %2 %3 %4" ).arg( subRect.x() ).arg( subRect.y() ).arg( subRect.width() ).arg( subRect.height() ) );