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 QgsDebugMsg( 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 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
367 if ( index >=
static_cast< qgssize >( mWidth ) *mHeight )
369 QgsDebugMsg( 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 );
398 QgsDebugMsg( QStringLiteral(
"Image not allocated" ) );
402 if ( index >=
static_cast< qgssize >( mImage->width() ) * mImage->height() )
404 QgsDebugMsg( 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 QgsDebugMsg( 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 QgsDebugMsg( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
827 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
828 return std::numeric_limits<double>::quiet_NaN();
830 return readValue( mData, mDataType, index );
837 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
839 return std::numeric_limits<double>::quiet_NaN();
841 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
843 QgsDebugMsg( 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).
void setIsData(qgssize index) SIP_HOLDGIL
Remove no data flag on pixel.
bool setValue(qgssize index, double value) SIP_HOLDGIL
Set value on index (indexed line by line)
void setValid(bool valid) SIP_HOLDGIL
Mark block as valid or invalid.
int width() const SIP_HOLDGIL
Returns the width (number of columns) of the raster block.
static int typeSize(Qgis::DataType dataType) SIP_HOLDGIL
Returns the size in bytes for the specified dataType.
bool isValid() const SIP_HOLDGIL
Returns true if the block is valid (correctly filled with 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.
Qgis::DataType dataType() const SIP_HOLDGIL
Returns data type.
bool isNoData(qgssize row, qgssize column) const SIP_HOLDGIL
Check if value at position is no data.
QRgb * colorData()
Gives direct read/write access to the raster RGB data.
double value(int row, int column) const SIP_HOLDGIL
Read a single value if type of block is numeric.
QRgb color(int row, int column) const SIP_HOLDGIL
Read a single color.
int dataTypeSize() const SIP_HOLDGIL
Data type size in bytes.
bool hasNoDataValue() const SIP_HOLDGIL
true if the block has no data value.
const quint8 * byteData() const
Gives direct access to the raster block data.
bool setColor(qgssize index, QRgb color) SIP_HOLDGIL
Set color on index (indexed line by line)
bool setColor(int row, int column, QRgb color) SIP_HOLDGIL
Set color on position.
static void writeValue(void *data, Qgis::DataType type, qgssize index, double value)
bool setIsNoData(qgssize index) SIP_HOLDGIL
Set no data on pixel.
bool isNoData(int row, int column) const SIP_HOLDGIL
Checks if value at position is no data.
bool isNoData(qgssize index) const SIP_HOLDGIL
Check if value at position is no data.
bool hasNoData() const SIP_HOLDGIL
Returns true if the block may contain no data.
bool setValue(int row, int column, double value) SIP_HOLDGIL
Set value on position.
void setError(const QgsError &error)
Sets the last error.
int height() const SIP_HOLDGIL
Returns the height (number of rows) of the raster block.
static double readValue(void *data, Qgis::DataType type, qgssize index)
bool setIsNoData(int row, int column) SIP_HOLDGIL
Set no data on pixel.
QRgb color(qgssize index) const SIP_HOLDGIL
Read a single value.
void setIsData(int row, int column) SIP_HOLDGIL
Remove no data flag on pixel.
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)
QList< QgsRasterRange > QgsRasterRangeList