18#ifndef QGSRASTERBLOCK_H
19#define QGSRASTERBLOCK_H
125 return typeSize( mDataType );
176 return mHasNoDataValue || mNoDataBitmap;
185 void setNoDataValue(
double noDataValue )
SIP_HOLDGIL;
212 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
224 return value(
static_cast< qgssize >( row ) * mWidth + column );
241 return valueAndNoData(
static_cast< qgssize >( row ) * mWidth + column, isNoData );
265 inline double valueAndNoData(
qgssize index,
bool &isNoData )
const SIP_SKIP;
278 return static_cast< const quint8 *
>( mData );
289 if ( !mImage )
return NO_DATA_COLOR;
291 return mImage->pixel( column, row );
301 const int row =
static_cast< int >( std::floor(
static_cast< double >( index ) / mWidth ) );
302 const int column = index % mWidth;
303 return color( row, column );
315 return isNoData(
static_cast< qgssize >( row ) * mWidth + column );
327 return isNoData( row *
static_cast< qgssize >( mWidth ) + column );
338 if ( !mHasNoDataValue && !mNoDataBitmap )
340 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
342 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
345 if ( mHasNoDataValue )
347 const double value = readValue( mData, mDataType, index );
348 return isNoDataValue( value );
351 if ( !mNoDataBitmap )
357 const int row =
static_cast< int >( index ) / mWidth;
358 const int column = index % mWidth;
359 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
360 const int bit = column % 8;
361 const int mask = 0x80 >> bit;
364 return mNoDataBitmap[byte] & mask;
376 return setValue(
static_cast< qgssize >( row ) * mWidth + column, value );
389 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
392 if ( index >=
static_cast< qgssize >( mWidth ) *mHeight )
394 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
397 writeValue( mData, mDataType, index, value );
410 return setColor(
static_cast< qgssize >( row ) * mWidth + column, color );
427 if ( index >=
static_cast< qgssize >( mImage->width() ) * mImage->height() )
429 QgsDebugError( QStringLiteral(
"index %1 out of range" ).arg( index ) );
434 QRgb *bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
450 return reinterpret_cast< QRgb *
>( mImage->bits() );
461 return setIsNoData(
static_cast< qgssize >( row ) * mWidth + column );
471 if ( mHasNoDataValue )
473 return setValue( index, mNoDataValue );
477 if ( !mNoDataBitmap )
479 if ( !createNoDataBitmap() )
485 const int row =
static_cast< int >( index ) / mWidth;
486 const int column = index % mWidth;
487 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
488 const int bit = column % 8;
489 const int nodata = 0x80 >> bit;
491 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
506 bool setIsNoDataExcept( QRect exceptRect );
518 setIsData(
static_cast< qgssize >( row )*mWidth + column );
530 if ( mHasNoDataValue )
536 if ( !mNoDataBitmap )
542 const int row =
static_cast< int >( index ) / mWidth;
543 const int column = index % mWidth;
544 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
545 const int bit = column % 8;
546 const int nodata = 0x80 >> bit;
547 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
559 bool fill(
double value );
570 void fill(
double value );
574 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot fill a block with %1 data type" ).arg(
qgsEnumValueToKey( sipCpp->dataType() ) ).toUtf8().constData() );
579 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot fill a block with %1 complex data type" ).arg(
qgsEnumValueToKey( sipCpp->dataType() ) ).toUtf8().constData() );
582 else if ( sipCpp->isEmpty() )
584 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot fill an empty block" ).toUtf8().constData() );
602 QByteArray data()
const;
612 void setData(
const QByteArray &data,
int offset = 0 );
620 char *bits(
int row,
int column )
SIP_SKIP;
657 const
char *constBits() const
SIP_SKIP;
666 static QString printValue(
double value,
bool localized = false );
676 static QString printValue(
float value,
bool localized = false )
SIP_SKIP;
683 bool convert(
Qgis::DataType destDataType );
688 QImage image() const;
694 bool setImage( const QImage *image );
700 inline static
void writeValue(
void *data,
Qgis::DataType type,
qgssize index,
double value )
SIP_SKIP;
707 void applyScaleOffset(
double scale,
double offset );
715 QString toString()
const;
813 static bool isNoDataValue(
double value,
double noDataValue )
818 return std::isnan( value ) ||
827 inline bool isNoDataValue(
double value )
const;
833 bool createNoDataBitmap();
862 bool mHasNoDataValue =
false;
867 static const QRgb NO_DATA_COLOR;
871 void *mData =
nullptr;
874 QImage *mImage =
nullptr;
879 char *mNoDataBitmap =
nullptr;
882 int mNoDataBitmapWidth = 0;
895 return std::numeric_limits<double>::quiet_NaN();
901 return static_cast< double >( (
static_cast< quint8 *
>( data ) )[index] );
903 return static_cast< double >( (
static_cast< qint8 *
>( data ) )[index] );
905 return static_cast< double >( (
static_cast< quint16 *
>( data ) )[index] );
907 return static_cast< double >( (
static_cast< qint16 *
>( data ) )[index] );
909 return static_cast< double >( (
static_cast< quint32 *
>( data ) )[index] );
911 return static_cast< double >( (
static_cast< qint32 *
>( data ) )[index] );
913 return static_cast< double >( (
static_cast< float *
>( data ) )[index] );
915 return static_cast< double >( (
static_cast< double *
>( data ) )[index] );
923 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
927 return std::numeric_limits<double>::quiet_NaN();
937 (
static_cast< quint8 *
>( data ) )[index] =
static_cast< quint8
>( value );
940 (
static_cast< qint8 *
>( data ) )[index] =
static_cast< qint8
>( value );
943 (
static_cast< quint16 *
>( data ) )[index] =
static_cast< quint16
>( value );
946 (
static_cast< qint16 *
>( data ) )[index] =
static_cast< qint16
>( value );
949 (
static_cast< quint32 *
>( data ) )[index] =
static_cast< quint32
>( value );
952 (
static_cast< qint32 *
>( data ) )[index] =
static_cast< qint32
>( value );
955 (
static_cast< float *
>( data ) )[index] =
static_cast< float >( value );
958 (
static_cast< double *
>( data ) )[index] = value;
967 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
976 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
977 return std::numeric_limits<double>::quiet_NaN();
979 return readValue( mData, mDataType, index );
986 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
988 return std::numeric_limits<double>::quiet_NaN();
990 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
992 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
994 return std::numeric_limits<double>::quiet_NaN();
997 const double val = readValue( mData, mDataType, index );
999 if ( !mHasNoDataValue && !mNoDataBitmap )
1005 if ( mHasNoDataValue )
1007 isNoData = isNoDataValue( val );
1011 if ( !mNoDataBitmap )
1023inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP
1025 return std::isnan( value ) ||
qgsDoubleNear( value, mNoDataValue );
Provides global constants and enumerations for use throughout the application.
DataType
Raster data types.
@ Float32
Thirty two bit floating point (float)
@ CFloat64
Complex Float64.
@ Int16
Sixteen bit signed integer (qint16)
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30)
@ UInt16
Sixteen bit unsigned integer (quint16)
@ Byte
Eight bit unsigned integer (quint8)
@ UnknownDataType
Unknown or unspecified type.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Int32
Thirty two bit signed integer (qint32)
@ Float64
Sixty four bit floating point (double)
@ CFloat32
Complex Float32.
@ UInt32
Thirty two bit unsigned integer (quint32)
A container for error messages.
bool isValid() const
Returns true if the block is valid (correctly filled with data).
QRgb color(int row, int column) const
Read a single color.
double value(int row, int column) const
Read a single value if type of block is numeric.
static bool typeIsNumeric(Qgis::DataType type)
Returns true if a data type is numeric.
void setValid(bool valid)
Mark block as valid or invalid.
int height() const
Returns the height (number of rows) of the raster block.
bool isNoData(qgssize row, qgssize column) const
Check if value at position is no data.
bool isNoData(qgssize index) const
Check if value at position is no data.
bool setColor(qgssize index, QRgb color)
Set color on index (indexed line by line)
int dataTypeSize() const
Data type size in bytes.
bool hasNoData() const
Returns true if the block may contain no data.
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.
static int typeSize(Qgis::DataType dataType)
Returns the size in bytes for the specified dataType.
bool setIsNoData(qgssize index)
Set no data on pixel.
bool setValue(qgssize index, double value)
Set value on index (indexed line by line)
QRgb * colorData()
Gives direct read/write access to the raster RGB data.
void setIsData(qgssize index)
Remove no data flag on pixel.
bool setValue(int row, int column, double value)
Set value on position.
bool setColor(int row, int column, QRgb color)
Set color on position.
bool isNoData(int row, int column) const
Checks if value at position is no data.
void setIsData(int row, int column)
Remove no data flag on pixel.
Qgis::DataType dataType() const
Returns data type.
bool hasNoDataValue() const
true if the block has no data value.
static bool typeIsComplex(Qgis::DataType type)
Returns true if a data type is a complex number type.
const quint8 * byteData() const
Gives direct access to the raster block data.
static void writeValue(void *data, Qgis::DataType type, qgssize index, double value)
int width() const
Returns the width (number of columns) of the raster block.
void setError(const QgsError &error)
Sets the last error.
static double readValue(void *data, Qgis::DataType type, qgssize index)
bool setIsNoData(int row, int column)
Set no data on pixel.
QRgb color(qgssize index) const
Read a single value.
A rectangle specified with double values.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
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 qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define QgsDebugError(str)
QList< QgsRasterRange > QgsRasterRangeList