18#ifndef QGSRASTERBLOCK_H
19#define QGSRASTERBLOCK_H
178 return mHasNoDataValue || mNoDataBitmap;
187 void setNoDataValue(
double noDataValue )
SIP_HOLDGIL;
214 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
226 return value(
static_cast< qgssize >( row ) * mWidth + column );
267 inline double valueAndNoData(
qgssize index,
bool &isNoData )
const SIP_SKIP;
280 return static_cast< const quint8 *
>( mData );
291 if ( !mImage )
return NO_DATA_COLOR;
293 return mImage->pixel( column, row );
303 const int row =
static_cast< int >( std::floor(
static_cast< double >( index ) / mWidth ) );
304 const int column = index % mWidth;
305 return color( row, column );
340 if ( !mHasNoDataValue && !mNoDataBitmap )
342 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
344 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
347 if ( mHasNoDataValue )
350 return isNoDataValue(
value );
353 if ( !mNoDataBitmap )
359 const int row =
static_cast< int >( index ) / mWidth;
360 const int column = index % mWidth;
361 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
362 const int bit = column % 8;
363 const int mask = 0x80 >> bit;
366 return mNoDataBitmap[byte] & mask;
391 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
394 if ( index >=
static_cast< qgssize >( mWidth ) *mHeight )
396 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
429 if ( index >=
static_cast< qgssize >( mImage->width() ) * mImage->height() )
431 QgsDebugError( QStringLiteral(
"index %1 out of range" ).arg( index ) );
436 QRgb *
bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
452 return reinterpret_cast< QRgb *
>( mImage->bits() );
473 if ( mHasNoDataValue )
475 return setValue( index, mNoDataValue );
479 if ( !mNoDataBitmap )
481 if ( !createNoDataBitmap() )
487 const int row =
static_cast< int >( index ) / mWidth;
488 const int column = index % mWidth;
489 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
490 const int bit = column % 8;
491 const int nodata = 0x80 >> bit;
493 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
508 bool setIsNoDataExcept( QRect exceptRect );
532 if ( mHasNoDataValue )
538 if ( !mNoDataBitmap )
544 const int row =
static_cast< int >( index ) / mWidth;
545 const int column = index % mWidth;
546 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
547 const int bit = column % 8;
548 const int nodata = 0x80 >> bit;
549 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
561 bool fill(
double value );
572 void fill(
double value );
576 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot fill a block with %1 data type" ).arg(
qgsEnumValueToKey( sipCpp->dataType() ) ).toUtf8().constData() );
581 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot fill a block with %1 complex data type" ).arg(
qgsEnumValueToKey( sipCpp->dataType() ) ).toUtf8().constData() );
584 else if ( sipCpp->isEmpty() )
586 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot fill an empty block" ).toUtf8().constData() );
604 QByteArray data()
const;
614 void setData(
const QByteArray &data,
int offset = 0 );
622 char *bits(
int row,
int column )
SIP_SKIP;
659 const
char *constBits() const
SIP_SKIP;
668 static QString printValue(
double value,
bool localized = false );
678 static QString printValue(
float value,
bool localized = false )
SIP_SKIP;
685 bool convert( Qgis::DataType destDataType );
690 QImage image() const;
696 bool setImage( const QImage *image );
699 inline static
double readValue(
void *data, Qgis::DataType type,
qgssize index )
SIP_SKIP;
702 inline static
void writeValue(
void *data, Qgis::DataType type,
qgssize index,
double value )
SIP_SKIP;
709 void applyScaleOffset(
double scale,
double offset );
717 QString toString()
const;
815 static bool isNoDataValue(
double value,
double noDataValue )
820 return std::isnan( value ) ||
829 inline bool isNoDataValue(
double value )
const;
835 bool createNoDataBitmap();
864 bool mHasNoDataValue =
false;
869 static const QRgb NO_DATA_COLOR;
873 void *mData =
nullptr;
876 QImage *mImage =
nullptr;
881 char *mNoDataBitmap =
nullptr;
884 int mNoDataBitmapWidth = 0;
897 return std::numeric_limits<double>::quiet_NaN();
903 return static_cast< double >( (
static_cast< quint8 *
>(
data ) )[index] );
905 return static_cast< double >( (
static_cast< qint8 *
>(
data ) )[index] );
907 return static_cast< double >( (
static_cast< quint16 *
>(
data ) )[index] );
909 return static_cast< double >( (
static_cast< qint16 *
>(
data ) )[index] );
911 return static_cast< double >( (
static_cast< quint32 *
>(
data ) )[index] );
913 return static_cast< double >( (
static_cast< qint32 *
>(
data ) )[index] );
915 return static_cast< double >( (
static_cast< float *
>(
data ) )[index] );
917 return static_cast< double >( (
static_cast< double *
>(
data ) )[index] );
929 return std::numeric_limits<double>::quiet_NaN();
939 (
static_cast< quint8 *
>(
data ) )[index] =
static_cast< quint8
>(
value );
942 (
static_cast< qint8 *
>(
data ) )[index] =
static_cast< qint8
>(
value );
945 (
static_cast< quint16 *
>(
data ) )[index] =
static_cast< quint16
>(
value );
948 (
static_cast< qint16 *
>(
data ) )[index] =
static_cast< qint16
>(
value );
951 (
static_cast< quint32 *
>(
data ) )[index] =
static_cast< quint32
>(
value );
954 (
static_cast< qint32 *
>(
data ) )[index] =
static_cast< qint32
>(
value );
957 (
static_cast< float *
>(
data ) )[index] =
static_cast< float >(
value );
960 (
static_cast< double *
>(
data ) )[index] =
value;
978 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
979 return std::numeric_limits<double>::quiet_NaN();
981 return readValue( mData, mDataType, index );
988 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
990 return std::numeric_limits<double>::quiet_NaN();
992 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
994 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
996 return std::numeric_limits<double>::quiet_NaN();
999 const double val =
readValue( mData, mDataType, index );
1001 if ( !mHasNoDataValue && !mNoDataBitmap )
1007 if ( mHasNoDataValue )
1013 if ( !mNoDataBitmap )
1025inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP
1027 return std::isnan( value ) ||
qgsDoubleNear( value, mNoDataValue );
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.
char * bits(int row, int column)
Returns a pointer to block 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.
QByteArray data() const
Gets access to raw data.
bool setIsNoData(qgssize index)
Set no data on pixel.
bool setValue(qgssize index, double value)
Set value on index (indexed line by line).
double noDataValue() const
Returns no data value.
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.
QgsError error() const
Returns the last error.
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.
bool reset(Qgis::DataType dataType, int width, int height)
Reset block.
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