18 #ifndef QGSRASTERBLOCK_H 19 #define QGSRASTERBLOCK_H 21 #include "qgis_core.h" 71 void setValid(
bool valid ) { mValid = valid; }
119 return typeSize( mDataType );
148 return mHasNoDataValue || mNoDataBitmap;
156 void setNoDataValue(
double noDataValue );
164 void resetNoDataValue();
179 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
189 double value(
int row,
int column )
const 191 return value( static_cast< qgssize >( row ) * mWidth + column );
208 return valueAndNoData( static_cast< qgssize >( row ) * mWidth + column, isNoData );
218 double value(
qgssize index )
const;
245 return static_cast< const quint8 *
>( mData );
253 QRgb
color(
int row,
int column )
const 255 if ( !mImage )
return NO_DATA_COLOR;
257 return mImage->pixel( column, row );
266 int row =
static_cast< int >( std::floor( static_cast< double >( index ) / mWidth ) );
267 int column = index % mWidth;
268 return color( row, column );
280 return isNoData( static_cast< qgssize >( row ) * mWidth + column );
292 return isNoData( row * static_cast< qgssize >( mWidth ) + column );
303 if ( !mHasNoDataValue && !mNoDataBitmap )
305 if ( index >= static_cast< qgssize >( mWidth )*mHeight )
307 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
310 if ( mHasNoDataValue )
312 double value = readValue( mData, mDataType, index );
313 return isNoDataValue( value );
316 if ( !mNoDataBitmap )
322 int row =
static_cast< int >( index ) / mWidth;
323 int column = index % mWidth;
324 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
325 int bit = column % 8;
326 int mask = 0x80 >> bit;
329 return mNoDataBitmap[byte] & mask;
340 return setValue( static_cast< qgssize >( row ) * mWidth + column, value );
352 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
355 if ( index >= static_cast< qgssize >( mWidth ) *mHeight )
357 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
360 writeValue( mData, mDataType, index, value );
372 return setColor( static_cast< qgssize >( row ) * mWidth + column, color );
384 QgsDebugMsg( QStringLiteral(
"Image not allocated" ) );
388 if ( index >= static_cast< qgssize >( mImage->width() ) * mImage->height() )
390 QgsDebugMsg( QStringLiteral(
"index %1 out of range" ).arg( index ) );
395 QRgb *bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
411 return reinterpret_cast< QRgb *
>( mImage->bits() );
421 return setIsNoData( static_cast< qgssize >( row ) * mWidth + column );
430 if ( mHasNoDataValue )
432 return setValue( index, mNoDataValue );
436 if ( !mNoDataBitmap )
438 if ( !createNoDataBitmap() )
444 int row =
static_cast< int >( index ) / mWidth;
445 int column = index % mWidth;
446 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
447 int bit = column % 8;
448 int nodata = 0x80 >> bit;
450 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
463 bool setIsNoDataExcept( QRect exceptRect );
475 setIsData( static_cast< qgssize >( row )*mWidth + column );
487 if ( mHasNoDataValue )
493 if ( !mNoDataBitmap )
499 int row =
static_cast< int >( index ) / mWidth;
500 int column = index % mWidth;
501 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
502 int bit = column % 8;
503 int nodata = 0x80 >> bit;
504 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
516 QByteArray data()
const;
527 void setData(
const QByteArray &data,
int offset = 0 );
535 char *bits(
int row,
int column )
SIP_SKIP;
555 static QString printValue(
double value );
565 static QString printValue(
float value )
SIP_SKIP;
576 QImage image()
const;
582 bool setImage(
const QImage *image );
596 void applyScaleOffset(
double scale,
double offset );
604 QString toString()
const;
623 int width()
const {
return mWidth; }
641 static bool isNoDataValue(
double value,
double noDataValue )
646 return std::isnan( value ) ||
654 bool isNoDataValue(
double value )
const;
659 bool createNoDataBitmap();
687 bool mHasNoDataValue =
false;
692 static const QRgb NO_DATA_COLOR;
696 void *mData =
nullptr;
699 QImage *mImage =
nullptr;
704 char *mNoDataBitmap =
nullptr;
707 int mNoDataBitmapWidth = 0;
720 return std::numeric_limits<double>::quiet_NaN();
726 return static_cast< double >( (
static_cast< quint8 *
>( data ) )[index] );
728 return static_cast< double >( (
static_cast< quint16 *
>( data ) )[index] );
730 return static_cast< double >( (
static_cast< qint16 *
>( data ) )[index] );
732 return static_cast< double >( (
static_cast< quint32 *
>( data ) )[index] );
734 return static_cast< double >( (
static_cast< qint32 *
>( data ) )[index] );
736 return static_cast< double >( (
static_cast< float *
>( data ) )[index] );
738 return static_cast< double >( (
static_cast< double *
>( data ) )[index] );
740 QgsDebugMsg( QStringLiteral(
"Data type %1 is not supported" ).arg( type ) );
744 return std::numeric_limits<double>::quiet_NaN();
754 (
static_cast< quint8 *
>( data ) )[index] =
static_cast< quint8
>( value );
757 (
static_cast< quint16 *
>( data ) )[index] =
static_cast< quint16
>( value );
760 (
static_cast< qint16 *
>( data ) )[index] =
static_cast< qint16
>( value );
763 (
static_cast< quint32 *
>( data ) )[index] =
static_cast< quint32
>( value );
766 (
static_cast< qint32 *
>( data ) )[index] =
static_cast< qint32
>( value );
769 (
static_cast< float *
>( data ) )[index] =
static_cast< float >( value );
772 (
static_cast< double *
>( data ) )[index] = value;
775 QgsDebugMsg( QStringLiteral(
"Data type %1 is not supported" ).arg( type ) );
784 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
785 return std::numeric_limits<double>::quiet_NaN();
787 return readValue( mData, mDataType, index );
794 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
796 return std::numeric_limits<double>::quiet_NaN();
798 if ( index >= static_cast< qgssize >( mWidth )*mHeight )
800 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
802 return std::numeric_limits<double>::quiet_NaN();
805 const double val = readValue( mData, mDataType, index );
807 if ( !mHasNoDataValue && !mNoDataBitmap )
813 if ( mHasNoDataValue )
815 isNoData = isNoDataValue( val );
819 if ( !mNoDataBitmap )
831 inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP 833 return std::isnan( value ) ||
qgsDoubleNear( value, mNoDataValue );
A rectangle specified with double values.
bool isNoData(qgssize row, qgssize column) const
Check if value at position is no data.
Thirty two bit signed integer (qint32)
bool isValid() const
Returns true if the block is valid (correctly filled with data).
static double readValue(void *data, Qgis::DataType type, qgssize index)
Qgis::DataType dataType() const
Returns data type.
bool setValue(int row, int column, double value)
Set value on position.
int height() const
Returns the height (number of rows) of the raster block.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
double valueAndNoData(int row, int column, bool &isNoData) const
Reads a single value from the pixel at row and column, if type of block is numeric.
Thirty two bit unsigned integer (quint32)
QRgb * colorData()
Gives direct read/write access to the raster RGB data.
DataType
Raster data types.
bool setColor(qgssize index, QRgb color)
Set color on index (indexed line by line)
Thirty two bit floating point (float)
bool isNoData(qgssize index) const
Check if value at position is no data.
Sixteen bit signed integer (qint16)
Sixty four bit floating point (double)
QgsError error() const
Returns the last error.
bool setIsNoData(int row, int column)
Set no data on pixel.
bool setColor(int row, int column, QRgb color)
Set color on position.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
void setIsData(qgssize index)
Remove no data flag on pixel.
const quint8 * byteData() const
Gives direct access to the raster block data.
void setError(const QgsError &error)
Sets the last error.
bool setIsNoData(qgssize index)
Set no data on pixel.
QRgb color(int row, int column) const
Read a single color.
void setIsData(int row, int column)
Remove no data flag on pixel.
Unknown or unspecified type.
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
bool isNoData(int row, int column) const
Checks if value at position is no data.
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...
int width() const
Returns the width (number of columns) of the raster block.
void setValid(bool valid)
Mark block as valid or invalid.
QRgb color(qgssize index) const
Read a single value.
static void writeValue(void *data, Qgis::DataType type, qgssize index, double value)
QList< QgsRasterRange > QgsRasterRangeList
bool setValue(qgssize index, double value)
Set value on index (indexed line by line)
QgsError is container for error messages (report).
double value(int row, int column) const
Read a single value if type of block is numeric.
bool hasNoDataValue() const
True if the block has no data value.
bool hasNoData() const
Returns true if the block may contain no data.
double noDataValue() const
Returns no data value.
Eight bit unsigned integer (quint8)
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.