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() )
    39     , mNoDataBitmap( nullptr )
    40     , mNoDataBitmapWidth( 0 )
    41     , mNoDataBitmapSize( 0 )
    47     , mDataType( theDataType )
    50     , mHeight( theHeight )
    51     , mHasNoDataValue( false )
    52     , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
    55     , mNoDataBitmap( nullptr )
    56     , mNoDataBitmapWidth( 0 )
    57     , mNoDataBitmapSize( 0 )
    59   ( void )
reset( mDataType, mWidth, mHeight );
    64     , mDataType( theDataType )
    67     , mHeight( theHeight )
    68     , mHasNoDataValue( true )
    69     , mNoDataValue( theNoDataValue )
    72     , mNoDataBitmap( nullptr )
    73     , mNoDataBitmapWidth( 0 )
    74     , mNoDataBitmapSize( 0 )
    76   ( void )
reset( mDataType, mWidth, mHeight, mNoDataValue );
    89   QgsDebugMsgLevel( 
QString( 
"theWidth= %1 theHeight = %2 theDataType = %3" ).arg( theWidth ).arg( theHeight ).arg( theDataType ), 4 );
    90   if ( !
reset( theDataType, theWidth, theHeight, std::numeric_limits<double>::quiet_NaN() ) )
    94   mHasNoDataValue = 
false;
   101   QgsDebugMsgLevel( 
QString( 
"theWidth= %1 theHeight = %2 theDataType = %3 theNoDataValue = %4" ).arg( theWidth ).arg( theHeight ).arg( theDataType ).arg( theNoDataValue ), 4 );
   108   mNoDataBitmap = 
nullptr;
   113   mHasNoDataValue = 
false;
   114   mNoDataValue = std::numeric_limits<double>::quiet_NaN();
   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   QgsDebugMsgLevel( 
QString( 
"mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5" ).arg( mWidth ).arg( mHeight ).arg( mDataType )
   149                     .arg( reinterpret_cast< ulong >( mData ) ).arg( reinterpret_cast< ulong >( mImage ) ), 4 );
   153 QImage::Format QgsRasterBlock::imageFormat( 
QGis::DataType theDataType )
   157     return QImage::Format_ARGB32;
   161     return QImage::Format_ARGB32_Premultiplied;
   163   return QImage::Format_Invalid;
   168   if ( theFormat == QImage::Format_ARGB32 )
   172   else if ( theFormat == QImage::Format_ARGB32_Premultiplied )
   181   QgsDebugMsgLevel( 
QString( 
"mWidth= %1 mHeight = %2 mDataType = %3 mData = %4 mImage = %5" ).arg( mWidth ).arg( mHeight ).arg( mDataType )
   182                     .arg( reinterpret_cast< ulong >( mData ) ).arg( reinterpret_cast< ulong >( mImage ) ), 4 );
   183   if ( mWidth == 0 || mHeight == 0 ||
   249       *noDataValue = -32768.0;
   253       *noDataValue = -2147483648.0;
   257       *noDataValue = -2147483648.0;
   277   return mHasNoDataValue || mNoDataBitmap;
   285   if ( qIsNaN( 
value ) ||
   295   return value( static_cast< qgssize >( row ) *mWidth + column );
   300   int row = floor( static_cast< double >( index ) / mWidth );
   301   int column = index % mWidth;
   302   return color( row, column );
   307   if ( !mImage ) 
return mNoDataColor;
   309   return mImage->
pixel( column, row );
   314   if ( !mHasNoDataValue && !mNoDataBitmap ) 
return false;
   315   if ( index >= static_cast< qgssize >( mWidth )*mHeight )
   317     QgsDebugMsg( 
QString( 
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
   320   if ( mHasNoDataValue )
   323     return isNoDataValue( value );
   326   if ( !mNoDataBitmap )
   332   int row = 
static_cast< int >( 
index ) / mWidth;
   333   int column = index % mWidth;
   334   qgssize byte = 
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
   335   int bit = column % 8;
   336   int mask = 0x80 >> bit;
   339   return mNoDataBitmap[byte] & mask;
   344   return isNoData( static_cast< qgssize >( row )*mWidth + column );
   354   if ( index >= static_cast< qgssize >( mWidth ) *mHeight )
   356     QgsDebugMsg( 
QString( 
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
   365   return setValue( static_cast< qgssize >( row )*mWidth + column, value );
   370   return setColor( static_cast< qgssize >( row ) *mWidth + column, color );
   381   if ( index >= static_cast< qgssize >( mImage->
width() ) * mImage->
height() )
   388   QRgb* 
bits = 
reinterpret_cast< QRgb* 
>( mImage->
bits() );
   395   return setIsNoData( static_cast< qgssize >( row )*mWidth + column );
   400   if ( mHasNoDataValue )
   402     return setValue( index, mNoDataValue );
   406     if ( !mNoDataBitmap )
   408       if ( !createNoDataBitmap() )
   414     int row = 
static_cast< int >( 
index ) / mWidth;
   415     int column = index % mWidth;
   416     qgssize byte = 
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
   417     int bit = column % 8;
   418     int nodata = 0x80 >> bit;
   420     mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
   430     if ( mHasNoDataValue )
   442       char *nodata = noDataByteArray.
data();
   443       for ( 
qgssize i = 0; i < static_cast< qgssize >( mWidth )*mHeight; i++ )
   445         memcpy( reinterpret_cast< char* >( mData ) + i*dataTypeSize, nodata, dataTypeSize );
   451       if ( !mNoDataBitmap )
   453         if ( !createNoDataBitmap() )
   459       memset( mNoDataBitmap, 0xff, mNoDataBitmapSize );
   472     mImage->
fill( mNoDataColor );
   479   int top = theExceptRect.
top();
   480   int bottom = theExceptRect.
bottom();
   481   int left = theExceptRect.
left();
   482   int right = theExceptRect.
right();
   483   top = qMin( qMax( top, 0 ), mHeight - 1 );
   484   left = qMin( qMax( left, 0 ), mWidth - 1 );
   485   bottom = qMax( 0, qMin( bottom, mHeight - 1 ) );
   486   right = qMax( 0, qMin( right, mWidth - 1 ) );
   491     if ( mHasNoDataValue )
   503       char *nodata = noDataByteArray.
data();
   505       for ( 
int c = 0; c < mWidth; c++ )
   507         memcpy( nodataRow + c*dataTypeSize, nodata, dataTypeSize );
   511       for ( 
int r = 0; r < mHeight; r++ )
   513         if ( r >= top && r <= bottom ) 
continue; 
   515         memcpy( reinterpret_cast< char* >( mData ) + i*dataTypeSize, nodataRow, dataTypeSize*mWidth );
   518       for ( 
int r = top; r <= bottom; r++ )
   522         memcpy( reinterpret_cast< char* >( mData ) + i*dataTypeSize, nodataRow, dataTypeSize*left );
   525         int w = mWidth - right - 1;
   526         memcpy( reinterpret_cast< char* >( mData ) + i*dataTypeSize, nodataRow, dataTypeSize*w );
   533       if ( !mNoDataBitmap )
   535         if ( !createNoDataBitmap() )
   542       char *nodataRow = 
new char[mNoDataBitmapWidth]; 
   544       memset( nodataRow, 0, mNoDataBitmapWidth );
   545       for ( 
int c = 0; c < mWidth; c ++ )
   549         char nodata = 0x80 >> bit;
   550         memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
   554       for ( 
int r = 0; r < mHeight; r++ )
   556         if ( r >= top && r <= bottom ) 
continue; 
   558         memcpy( mNoDataBitmap + i, nodataRow, mNoDataBitmapWidth );
   561       memset( nodataRow, 0, mNoDataBitmapWidth );
   562       for ( 
int c = 0; c < mWidth; c ++ )
   564         if ( c >= left && c <= right ) 
continue; 
   567         char nodata = 0x80 >> bit;
   568         memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
   570       for ( 
int r = top; r <= bottom; r++ )
   573         memcpy( mNoDataBitmap + i, nodataRow, mNoDataBitmapWidth );
   588     if ( mImage->
width() != mWidth ||  mImage->
height() != mHeight )
   597     if ( mImage->
depth() != 32 )
   603     QRgb nodataRgba = mNoDataColor;
   604     QRgb *nodataRow = 
new QRgb[mWidth]; 
   605     int rgbSize = 
sizeof( QRgb );
   606     for ( 
int c = 0; c < mWidth; c ++ )
   608       nodataRow[c] = nodataRgba;
   612     for ( 
int r = 0; r < mHeight; r++ )
   614       if ( r >= top && r <= bottom ) 
continue; 
   616       memcpy( reinterpret_cast< void * >( mImage->
bits() + rgbSize*i ), nodataRow, rgbSize*mWidth );
   619     for ( 
int r = top; r <= bottom; r++ )
   625         memcpy( reinterpret_cast< void * >( mImage->
bits() + rgbSize*i ), nodataRow, rgbSize*( left - 1 ) );
   629       int w = mWidth - right - 1;
   630       memcpy( reinterpret_cast< void * >( mImage->
bits() + rgbSize*i ), nodataRow, rgbSize*w );
   639   setIsData( static_cast< qgssize >( row )*mWidth + column );
   644   if ( mHasNoDataValue )
   650   if ( !mNoDataBitmap )
   656   int row = 
static_cast< int >( 
index ) / mWidth;
   657   int column = index % mWidth;
   658   qgssize byte = 
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
   659   int bit = column % 8;
   660   int nodata = 0x80 >> bit;
   661   mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
   667   if ( index >= static_cast< qgssize >( mWidth )*mHeight )
   674     return reinterpret_cast< char* 
>( mData ) + index * mTypeSize;
   676   if ( mImage && mImage->
bits() )
   678     return reinterpret_cast< char* 
>( mImage->
bits() + index * 4 );
   686   return bits( static_cast< qgssize >( row )*mWidth + column );
   693     return reinterpret_cast< char* 
>( mData );
   695   if ( mImage && mImage->
bits() )
   697     return reinterpret_cast< char* 
>( mImage->
bits() );
   706   if ( destDataType == mDataType ) 
return true;
   710     void *data = 
convert( mData, mDataType, destDataType, static_cast< qgssize >( mWidth ) * static_cast< qgssize >( mHeight ) );
   719     mDataType = destDataType;
   724     QImage::Format format = imageFormat( destDataType );
   727     mDataType = destDataType;
   742   if ( scale == 1.0 && offset == 0.0 ) 
return;
   745   for ( 
qgssize i = 0; i < size; ++i )
   759   qgssize size = 
static_cast< qgssize >( mWidth ) * static_cast< qgssize >( mHeight );
   760   for ( 
qgssize i = 0; i < size; ++i )
   762     double val = 
value( i );
   786   mImage = 
new QImage( *image );
   787   mWidth = mImage->
width();
   788   mHeight = mImage->
height();
   791   mNoDataValue = std::numeric_limits<double>::quiet_NaN();
   821   for ( 
int i = 15; i <= 17; i++ )
   823     s.
setNum( value, 
'g', i );
   830   QgsDebugMsg( 
"Cannot correctly parse printed value" );
   842   for ( 
int i = 6; i <= 9; i++ )
   844     s.
setNum( value, 
'g', i );
   851   QgsDebugMsg( 
"Cannot correctly parse printed value" );
   857   int destDataTypeSize = 
typeSize( destDataType );
   858   void *destData = 
qgsMalloc( destDataTypeSize * size );
   859   for ( 
qgssize i = 0; i < size; i++ )
   862     writeValue( destData, destDataType, i, value );
   873   ba.
resize( static_cast< int >( size ) );
   874   char * data = ba.
data();
   882   switch ( theDataType )
   885       uc = 
static_cast< quint8 
>( theValue );
   886       memcpy( data, &uc, size );
   889       us = 
static_cast< quint16 
>( theValue );
   890       memcpy( data, &us, size );
   893       s = 
static_cast< qint16 
>( theValue );
   894       memcpy( data, &s, size );
   897       ui = 
static_cast< quint32 
>( theValue );
   898       memcpy( data, &ui, size );
   901       i = 
static_cast< qint32 
>( theValue );
   902       memcpy( data, &i, size );
   905       f = 
static_cast< float >( theValue );
   906       memcpy( data, &f, size );
   909       d = 
static_cast< double >( theValue );
   910       memcpy( data, &d, size );
   918 bool QgsRasterBlock::createNoDataBitmap()
   920   mNoDataBitmapWidth = mWidth / 8 + 1;
   921   mNoDataBitmapSize = 
static_cast< qgssize >( mNoDataBitmapWidth ) * mHeight;
   923   mNoDataBitmap = 
reinterpret_cast< char* 
>( 
qgsMalloc( mNoDataBitmapSize ) );
   924   if ( !mNoDataBitmap )
   926     QgsDebugMsg( 
QString( 
"Couldn't allocate no data memory of %1 bytes" ).arg( mNoDataBitmapSize ) );
   929   memset( mNoDataBitmap, 0, mNoDataBitmapSize );
   935   return QString( 
"dataType = %1 width = %2 height = %3" )
   936          .
arg( mDataType ).
arg( mWidth ).
arg( mHeight );
   943   double xRes = theExtent.
width() / theWidth;
   944   double yRes = theExtent.
height() / theHeight;
   946   QgsDebugMsgLevel( 
QString( 
"theWidth = %1 theHeight = %2 xRes = %3 yRes = %4" ).arg( theWidth ).arg( theHeight ).arg( xRes ).arg( yRes ), 4 );
   949   int bottom = theHeight - 1;
   951   int right = theWidth - 1;
   959     bottom = qRound(( theExtent.
yMaximum() - theSubExtent.
yMinimum() ) / yRes ) - 1;
   968     right = qRound(( theSubExtent.
xMaximum() - theExtent.
xMinimum() ) / xRes ) - 1;
 Eight bit unsigned integer (quint8) 
 
A rectangle specified with double values. 
 
bool convert(QGis::DataType destDataType)
Convert data to different type. 
 
static QString printValue(double value)
Print double value with all necessary significant digits. 
 
void * qgsMalloc(size_t size)
Allocates size bytes and returns a pointer to the allocated memory. 
 
Unknown or unspecified type. 
 
bool setIsNoData()
Set the whole block to no data. 
 
static bool contains(double value, const QgsRasterRangeList &rangeList)
Test if value is within the list of ranges. 
 
bool qgsFloatNear(float a, float b, float epsilon=4 *FLT_EPSILON)
Compare two floats (but allow some difference) 
 
static bool typeIsNumeric(QGis::DataType type)
Returns true if data type is numeric. 
 
void applyNoDataValues(const QgsRasterRangeList &rangeList)
 
bool setValue(int row, int column, double value)
Set value on position. 
 
Thirty two bit floating point (float) 
 
The QGis class provides global constants for use throughout the application. 
 
double toDouble(bool *ok) const
 
bool isNoData(int row, int column)
Check if value at position is no data. 
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference) 
 
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal. 
 
bool setColor(int row, int column, QRgb color)
Set color on position. 
 
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax 
 
virtual ~QgsRasterBlock()
 
static QGis::DataType typeWithNoDataValue(QGis::DataType dataType, double *noDataValue)
For given data type returns wider type and sets no data value. 
 
QRgb pixel(int x, int y) const
 
Sixteen bit unsigned integer (quint16) 
 
Sixty four bit floating point (double) 
 
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied. 
 
void fill(uint pixelValue)
 
bool setImage(const QImage *image)
set image. 
 
#define QgsDebugMsgLevel(str, level)
 
Thirty two bit signed integer (qint32) 
 
double width() const
Width of the rectangle. 
 
static bool typeIsColor(QGis::DataType type)
Returns true if data type is color. 
 
Thirty two bit unsigned integer (quint32) 
 
QRgb color(int row, int column) const
Read a single color. 
 
bool setIsNoDataExcept(QRect theExceptRect)
Set the whole block to no data except specified rectangle. 
 
void setIsData(int row, int column)
Remove no data flag on pixel. 
 
char * bits()
Get pointer to data. 
 
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32. 
 
static int typeSize(int dataType)
 
bool isEmpty() const
Returns true if block is empty, i.e. 
 
Sixteen bit signed integer (qint16) 
 
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
 
bool reset(QGis::DataType theDataType, int theWidth, int theHeight)
Reset block. 
 
double yMinimum() const
Get the y minimum value (bottom side of rectangle) 
 
QImage image() const
Get image if type is color. 
 
double xMaximum() const
Get the x maximum value (right side of rectangle) 
 
static void writeValue(void *data, QGis::DataType type, qgssize index, double value)
 
QGis::DataType dataType() const
Returns data type. 
 
void applyScaleOffset(double scale, double offset)
Apply band scale and offset to raster block values @note added in 2.3. 
 
QString & setNum(short n, int base)
 
float toFloat(bool *ok) const
 
static QByteArray valueBytes(QGis::DataType theDataType, double theValue)
Get byte array representing a value. 
 
DataType
Raster data types. 
 
double value(int row, int column) const
Read a single value if type of block is numeric. 
 
double xMinimum() const
Get the x minimum value (left side of rectangle) 
 
double yMaximum() const
Get the y maximum value (top side of rectangle) 
 
static double readValue(void *data, QGis::DataType type, qgssize index)
 
static QRect subRect(const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent)
For theExtent and theWidht, theHeight find rectangle covered by subextent. 
 
bool hasNoData() const
Returns true if the block may contain no data. 
 
double noDataValue() const
Return no data value. 
 
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
 
void qgsFree(void *ptr)
Frees the memory space pointed to by ptr. 
 
double height() const
Height of the rectangle.