18#ifndef QGSRASTERBLOCK_H
19#define QGSRASTERBLOCK_H
125 return typeSize( mDataType );
157 return mHasNoDataValue || mNoDataBitmap;
166 void setNoDataValue(
double noDataValue )
SIP_HOLDGIL;
193 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
205 return value(
static_cast< qgssize >( row ) * mWidth + column );
222 return valueAndNoData(
static_cast< qgssize >( row ) * mWidth + column, isNoData );
246 inline double valueAndNoData(
qgssize index,
bool &isNoData )
const SIP_SKIP;
259 return static_cast< const quint8 *
>( mData );
270 if ( !mImage )
return NO_DATA_COLOR;
272 return mImage->pixel( column, row );
282 const int row =
static_cast< int >( std::floor(
static_cast< double >( index ) / mWidth ) );
283 const int column = index % mWidth;
284 return color( row, column );
296 return isNoData(
static_cast< qgssize >( row ) * mWidth + column );
308 return isNoData( row *
static_cast< qgssize >( mWidth ) + column );
319 if ( !mHasNoDataValue && !mNoDataBitmap )
321 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
323 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
326 if ( mHasNoDataValue )
328 const double value = readValue( mData, mDataType, index );
329 return isNoDataValue( value );
332 if ( !mNoDataBitmap )
338 const int row =
static_cast< int >( index ) / mWidth;
339 const int column = index % mWidth;
340 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
341 const int bit = column % 8;
342 const int mask = 0x80 >> bit;
345 return mNoDataBitmap[byte] & mask;
357 return setValue(
static_cast< qgssize >( row ) * mWidth + column, value );
370 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
373 if ( index >=
static_cast< qgssize >( mWidth ) *mHeight )
375 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
378 writeValue( mData, mDataType, index, value );
391 return setColor(
static_cast< qgssize >( row ) * mWidth + column, color );
408 if ( index >=
static_cast< qgssize >( mImage->width() ) * mImage->height() )
410 QgsDebugError( QStringLiteral(
"index %1 out of range" ).arg( index ) );
415 QRgb *bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
431 return reinterpret_cast< QRgb *
>( mImage->bits() );
442 return setIsNoData(
static_cast< qgssize >( row ) * mWidth + column );
452 if ( mHasNoDataValue )
454 return setValue( index, mNoDataValue );
458 if ( !mNoDataBitmap )
460 if ( !createNoDataBitmap() )
466 const int row =
static_cast< int >( index ) / mWidth;
467 const int column = index % mWidth;
468 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
469 const int bit = column % 8;
470 const int nodata = 0x80 >> bit;
472 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
487 bool setIsNoDataExcept( QRect exceptRect );
499 setIsData(
static_cast< qgssize >( row )*mWidth + column );
511 if ( mHasNoDataValue )
517 if ( !mNoDataBitmap )
523 const int row =
static_cast< int >( index ) / mWidth;
524 const int column = index % mWidth;
525 const qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
526 const int bit = column % 8;
527 const int nodata = 0x80 >> bit;
528 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
539 QByteArray data()
const;
549 void setData(
const QByteArray &data,
int offset = 0 );
557 char *bits(
int row,
int column )
SIP_SKIP;
594 const
char *constBits() const
SIP_SKIP;
603 static QString printValue(
double value,
bool localized = false );
613 static QString printValue(
float value,
bool localized = false )
SIP_SKIP;
620 bool convert(
Qgis::DataType destDataType );
625 QImage image() const;
631 bool setImage( const QImage *image );
637 inline static
void writeValue(
void *data,
Qgis::DataType type,
qgssize index,
double value )
SIP_SKIP;
644 void applyScaleOffset(
double scale,
double offset );
652 QString toString()
const;
750 static bool isNoDataValue(
double value,
double noDataValue )
755 return std::isnan( value ) ||
764 inline bool isNoDataValue(
double value )
const;
770 bool createNoDataBitmap();
799 bool mHasNoDataValue =
false;
804 static const QRgb NO_DATA_COLOR;
808 void *mData =
nullptr;
811 QImage *mImage =
nullptr;
816 char *mNoDataBitmap =
nullptr;
819 int mNoDataBitmapWidth = 0;
832 return std::numeric_limits<double>::quiet_NaN();
838 return static_cast< double >( (
static_cast< quint8 *
>( data ) )[index] );
840 return static_cast< double >( (
static_cast< qint8 *
>( data ) )[index] );
842 return static_cast< double >( (
static_cast< quint16 *
>( data ) )[index] );
844 return static_cast< double >( (
static_cast< qint16 *
>( data ) )[index] );
846 return static_cast< double >( (
static_cast< quint32 *
>( data ) )[index] );
848 return static_cast< double >( (
static_cast< qint32 *
>( data ) )[index] );
850 return static_cast< double >( (
static_cast< float *
>( data ) )[index] );
852 return static_cast< double >( (
static_cast< double *
>( data ) )[index] );
860 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
864 return std::numeric_limits<double>::quiet_NaN();
874 (
static_cast< quint8 *
>( data ) )[index] =
static_cast< quint8
>( value );
877 (
static_cast< qint8 *
>( data ) )[index] =
static_cast< qint8
>( value );
880 (
static_cast< quint16 *
>( data ) )[index] =
static_cast< quint16
>( value );
883 (
static_cast< qint16 *
>( data ) )[index] =
static_cast< qint16
>( value );
886 (
static_cast< quint32 *
>( data ) )[index] =
static_cast< quint32
>( value );
889 (
static_cast< qint32 *
>( data ) )[index] =
static_cast< qint32
>( value );
892 (
static_cast< float *
>( data ) )[index] =
static_cast< float >( value );
895 (
static_cast< double *
>( data ) )[index] = value;
904 QgsDebugError( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
913 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
914 return std::numeric_limits<double>::quiet_NaN();
916 return readValue( mData, mDataType, index );
923 QgsDebugError( QStringLiteral(
"Data block not allocated" ) );
925 return std::numeric_limits<double>::quiet_NaN();
927 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
929 QgsDebugError( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
931 return std::numeric_limits<double>::quiet_NaN();
934 const double val = readValue( mData, mDataType, index );
936 if ( !mHasNoDataValue && !mNoDataBitmap )
942 if ( mHasNoDataValue )
944 isNoData = isNoDataValue( val );
948 if ( !mNoDataBitmap )
960inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP
962 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)
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.
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