18#ifndef QGSRASTERBLOCK_H
19#define QGSRASTERBLOCK_H
125 return typeSize( mDataType );
155 return mHasNoDataValue || mNoDataBitmap;
163 void setNoDataValue(
double noDataValue )
SIP_HOLDGIL;
187 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
199 return value(
static_cast< qgssize >( row ) * mWidth + column );
216 return valueAndNoData(
static_cast< qgssize >( row ) * mWidth + column, isNoData );
240 inline double valueAndNoData(
qgssize index,
bool &isNoData )
const SIP_SKIP;
253 return static_cast< const quint8 *
>( mData );
264 if ( !mImage )
return NO_DATA_COLOR;
266 return mImage->pixel( column, row );
276 const int row =
static_cast< int >( std::floor(
static_cast< double >( index ) / mWidth ) );
277 const int column = index % mWidth;
278 return color( row, column );
290 return isNoData(
static_cast< qgssize >( row ) * mWidth + column );
302 return isNoData( row *
static_cast< qgssize >( mWidth ) + column );
313 if ( !mHasNoDataValue && !mNoDataBitmap )
315 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
317 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
320 if ( mHasNoDataValue )
322 const double value = readValue( mData, mDataType, index );
323 return isNoDataValue( value );
326 if ( !mNoDataBitmap )
332 const int row =
static_cast< int >( index ) / mWidth;
333 const int column = index % mWidth;
334 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
335 const int bit = column % 8;
336 const int mask = 0x80 >> bit;
339 return mNoDataBitmap[byte] & mask;
351 return setValue(
static_cast< qgssize >( row ) * mWidth + column, value );
364 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
367 if ( index >=
static_cast< qgssize >( mWidth ) *mHeight )
369 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
372 writeValue( mData, mDataType, index, value );
385 return setColor(
static_cast< qgssize >( row ) * mWidth + column, color );
402 if ( index >=
static_cast< qgssize >( mImage->width() ) * mImage->height() )
404 QgsDebugError( QStringLiteral(
"index %1 out of range" ).arg( index ) );
409 QRgb *bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
425 return reinterpret_cast< QRgb *
>( mImage->bits() );
436 return setIsNoData(
static_cast< qgssize >( row ) * mWidth + column );
446 if ( mHasNoDataValue )
448 return setValue( index, mNoDataValue );
452 if ( !mNoDataBitmap )
454 if ( !createNoDataBitmap() )
460 const int row =
static_cast< int >( index ) / mWidth;
461 const int column = index % mWidth;
462 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
463 const int bit = column % 8;
464 const int nodata = 0x80 >> bit;
466 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
481 bool setIsNoDataExcept( QRect exceptRect );
494 setIsData(
static_cast< qgssize >( row )*mWidth + column );
507 if ( mHasNoDataValue )
513 if ( !mNoDataBitmap )
519 const int row =
static_cast< int >( index ) / mWidth;
520 const int column = index % mWidth;
521 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
522 const int bit = column % 8;
523 const int nodata = 0x80 >> bit;
524 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
536 QByteArray data()
const;
547 void setData(
const QByteArray &data,
int offset = 0 );
555 char *bits(
int row,
int column )
SIP_SKIP;
576 static QString printValue(
double value );
586 static QString printValue(
float value )
SIP_SKIP;
593 bool convert(
Qgis::DataType destDataType );
598 QImage image() const;
604 bool setImage( const QImage *image );
610 inline static
void writeValue(
void *data,
Qgis::DataType type,
qgssize index,
double value )
SIP_SKIP;
618 void applyScaleOffset(
double scale,
double offset );
626 QString toString()
const;
664 static bool isNoDataValue(
double value,
double noDataValue )
669 return std::isnan( value ) ||
678 inline bool isNoDataValue(
double value )
const;
684 bool createNoDataBitmap();
713 bool mHasNoDataValue =
false;
718 static const QRgb NO_DATA_COLOR;
722 void *mData =
nullptr;
725 QImage *mImage =
nullptr;
730 char *mNoDataBitmap =
nullptr;
733 int mNoDataBitmapWidth = 0;
746 return std::numeric_limits<double>::quiet_NaN();
752 return static_cast< double >( (
static_cast< quint8 *
>( data ) )[index] );
754 return static_cast< double >( (
static_cast< qint8 *
>( data ) )[index] );
756 return static_cast< double >( (
static_cast< quint16 *
>( data ) )[index] );
758 return static_cast< double >( (
static_cast< qint16 *
>( data ) )[index] );
760 return static_cast< double >( (
static_cast< quint32 *
>( data ) )[index] );
762 return static_cast< double >( (
static_cast< qint32 *
>( data ) )[index] );
764 return static_cast< double >( (
static_cast< float *
>( data ) )[index] );
766 return static_cast< double >( (
static_cast< double *
>( data ) )[index] );
774 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
778 return std::numeric_limits<double>::quiet_NaN();
788 (
static_cast< quint8 *
>( data ) )[index] =
static_cast< quint8
>( value );
791 (
static_cast< qint8 *
>( data ) )[index] =
static_cast< qint8
>( value );
794 (
static_cast< quint16 *
>( data ) )[index] =
static_cast< quint16
>( value );
797 (
static_cast< qint16 *
>( data ) )[index] =
static_cast< qint16
>( value );
800 (
static_cast< quint32 *
>( data ) )[index] =
static_cast< quint32
>( value );
803 (
static_cast< qint32 *
>( data ) )[index] =
static_cast< qint32
>( value );
806 (
static_cast< float *
>( data ) )[index] =
static_cast< float >( value );
809 (
static_cast< double *
>( data ) )[index] = value;
818 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
827 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
828 return std::numeric_limits<double>::quiet_NaN();
830 return readValue( mData, mDataType, index );
837 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
839 return std::numeric_limits<double>::quiet_NaN();
841 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
843 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
845 return std::numeric_limits<double>::quiet_NaN();
848 const double val = readValue( mData, mDataType, index );
850 if ( !mHasNoDataValue && !mNoDataBitmap )
856 if ( mHasNoDataValue )
858 isNoData = isNoDataValue( val );
862 if ( !mNoDataBitmap )
874inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP
876 return std::isnan( value ) ||
qgsDoubleNear( value, mNoDataValue );
The Qgis class provides global constants 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)
QgsError is container for error messages (report).
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.
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.
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.
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