18#ifndef QGSRASTERBLOCK_H
19#define QGSRASTERBLOCK_H
125 return typeSize( mDataType );
155 return mHasNoDataValue || mNoDataBitmap;
162 void setNoDataValue(
double noDataValue )
SIP_HOLDGIL;
185 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
197 return value(
static_cast< qgssize >( row ) * mWidth + column );
214 return valueAndNoData(
static_cast< qgssize >( row ) * mWidth + column, isNoData );
238 inline double valueAndNoData(
qgssize index,
bool &isNoData )
const SIP_SKIP;
251 return static_cast< const quint8 *
>( mData );
262 if ( !mImage )
return NO_DATA_COLOR;
264 return mImage->pixel( column, row );
274 const int row =
static_cast< int >( std::floor(
static_cast< double >( index ) / mWidth ) );
275 const int column = index % mWidth;
276 return color( row, column );
288 return isNoData(
static_cast< qgssize >( row ) * mWidth + column );
300 return isNoData( row *
static_cast< qgssize >( mWidth ) + column );
311 if ( !mHasNoDataValue && !mNoDataBitmap )
313 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
315 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
318 if ( mHasNoDataValue )
320 const double value = readValue( mData, mDataType, index );
321 return isNoDataValue( value );
324 if ( !mNoDataBitmap )
330 const int row =
static_cast< int >( index ) / mWidth;
331 const int column = index % mWidth;
332 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
333 const int bit = column % 8;
334 const int mask = 0x80 >> bit;
337 return mNoDataBitmap[byte] & mask;
349 return setValue(
static_cast< qgssize >( row ) * mWidth + column, value );
362 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
365 if ( index >=
static_cast< qgssize >( mWidth ) *mHeight )
367 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
370 writeValue( mData, mDataType, index, value );
383 return setColor(
static_cast< qgssize >( row ) * mWidth + column, color );
400 if ( index >=
static_cast< qgssize >( mImage->width() ) * mImage->height() )
402 QgsDebugError( QStringLiteral(
"index %1 out of range" ).arg( index ) );
407 QRgb *bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
423 return reinterpret_cast< QRgb *
>( mImage->bits() );
434 return setIsNoData(
static_cast< qgssize >( row ) * mWidth + column );
444 if ( mHasNoDataValue )
446 return setValue( index, mNoDataValue );
450 if ( !mNoDataBitmap )
452 if ( !createNoDataBitmap() )
458 const int row =
static_cast< int >( index ) / mWidth;
459 const int column = index % mWidth;
460 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
461 const int bit = column % 8;
462 const int nodata = 0x80 >> bit;
464 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
479 bool setIsNoDataExcept( QRect exceptRect );
491 setIsData(
static_cast< qgssize >( row )*mWidth + column );
503 if ( mHasNoDataValue )
509 if ( !mNoDataBitmap )
515 const int row =
static_cast< int >( index ) / mWidth;
516 const int column = index % mWidth;
517 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
518 const int bit = column % 8;
519 const int nodata = 0x80 >> bit;
520 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
531 QByteArray data()
const;
541 void setData(
const QByteArray &data,
int offset = 0 );
549 char *bits(
int row,
int column )
SIP_SKIP;
570 static QString printValue(
double value );
579 static QString printValue(
float value )
SIP_SKIP;
586 bool convert(
Qgis::DataType destDataType );
591 QImage image() const;
597 bool setImage( const QImage *image );
603 inline static
void writeValue(
void *data,
Qgis::DataType type,
qgssize index,
double value )
SIP_SKIP;
610 void applyScaleOffset(
double scale,
double offset );
618 QString toString()
const;
654 static bool isNoDataValue(
double value,
double noDataValue )
659 return std::isnan( value ) ||
668 inline bool isNoDataValue(
double value )
const;
674 bool createNoDataBitmap();
703 bool mHasNoDataValue =
false;
708 static const QRgb NO_DATA_COLOR;
712 void *mData =
nullptr;
715 QImage *mImage =
nullptr;
720 char *mNoDataBitmap =
nullptr;
723 int mNoDataBitmapWidth = 0;
736 return std::numeric_limits<double>::quiet_NaN();
742 return static_cast< double >( (
static_cast< quint8 *
>( data ) )[index] );
744 return static_cast< double >( (
static_cast< qint8 *
>( data ) )[index] );
746 return static_cast< double >( (
static_cast< quint16 *
>( data ) )[index] );
748 return static_cast< double >( (
static_cast< qint16 *
>( data ) )[index] );
750 return static_cast< double >( (
static_cast< quint32 *
>( data ) )[index] );
752 return static_cast< double >( (
static_cast< qint32 *
>( data ) )[index] );
754 return static_cast< double >( (
static_cast< float *
>( data ) )[index] );
756 return static_cast< double >( (
static_cast< double *
>( data ) )[index] );
764 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
768 return std::numeric_limits<double>::quiet_NaN();
778 (
static_cast< quint8 *
>( data ) )[index] =
static_cast< quint8
>( value );
781 (
static_cast< qint8 *
>( data ) )[index] =
static_cast< qint8
>( value );
784 (
static_cast< quint16 *
>( data ) )[index] =
static_cast< quint16
>( value );
787 (
static_cast< qint16 *
>( data ) )[index] =
static_cast< qint16
>( value );
790 (
static_cast< quint32 *
>( data ) )[index] =
static_cast< quint32
>( value );
793 (
static_cast< qint32 *
>( data ) )[index] =
static_cast< qint32
>( value );
796 (
static_cast< float *
>( data ) )[index] =
static_cast< float >( value );
799 (
static_cast< double *
>( data ) )[index] = value;
808 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
817 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
818 return std::numeric_limits<double>::quiet_NaN();
820 return readValue( mData, mDataType, index );
827 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
829 return std::numeric_limits<double>::quiet_NaN();
831 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
833 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
835 return std::numeric_limits<double>::quiet_NaN();
838 const double val = readValue( mData, mDataType, index );
840 if ( !mHasNoDataValue && !mNoDataBitmap )
846 if ( mHasNoDataValue )
848 isNoData = isNoDataValue( val );
852 if ( !mNoDataBitmap )
864inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP
866 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