18 #ifndef QGSRASTERBLOCK_H 19 #define QGSRASTERBLOCK_H 21 #include "qgis_core.h" 71 void setValid(
bool valid ) { mValid = valid; }
119 return typeSize( mDataType );
149 return mHasNoDataValue || mNoDataBitmap;
157 void setNoDataValue(
double noDataValue );
165 void resetNoDataValue();
181 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
191 double value(
int row,
int column )
const 193 return value( static_cast< qgssize >( row ) * mWidth + column );
210 return valueAndNoData( static_cast< qgssize >( row ) * mWidth + column, isNoData );
220 double value(
qgssize index )
const;
247 return static_cast< const quint8 *
>( mData );
256 QRgb
color(
int row,
int column )
const 258 if ( !mImage )
return NO_DATA_COLOR;
260 return mImage->pixel( column, row );
270 int row =
static_cast< int >( std::floor( static_cast< double >( index ) / mWidth ) );
271 int column = index % mWidth;
272 return color( row, column );
284 return isNoData( static_cast< qgssize >( row ) * mWidth + column );
296 return isNoData( row * static_cast< qgssize >( mWidth ) + column );
307 if ( !mHasNoDataValue && !mNoDataBitmap )
309 if ( index >= static_cast< qgssize >( mWidth )*mHeight )
311 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
314 if ( mHasNoDataValue )
316 double value = readValue( mData, mDataType, index );
317 return isNoDataValue( value );
320 if ( !mNoDataBitmap )
326 int row =
static_cast< int >( index ) / mWidth;
327 int column = index % mWidth;
328 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
329 int bit = column % 8;
330 int mask = 0x80 >> bit;
333 return mNoDataBitmap[byte] & mask;
345 return setValue( static_cast< qgssize >( row ) * mWidth + column, value );
358 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
361 if ( index >= static_cast< qgssize >( mWidth ) *mHeight )
363 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
366 writeValue( mData, mDataType, index, value );
379 return setColor( static_cast< qgssize >( row ) * mWidth + column, color );
392 QgsDebugMsg( QStringLiteral(
"Image not allocated" ) );
396 if ( index >= static_cast< qgssize >( mImage->width() ) * mImage->height() )
398 QgsDebugMsg( QStringLiteral(
"index %1 out of range" ).arg( index ) );
403 QRgb *bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
419 return reinterpret_cast< QRgb *
>( mImage->bits() );
430 return setIsNoData( static_cast< qgssize >( row ) * mWidth + column );
440 if ( mHasNoDataValue )
442 return setValue( index, mNoDataValue );
446 if ( !mNoDataBitmap )
448 if ( !createNoDataBitmap() )
454 int row =
static_cast< int >( index ) / mWidth;
455 int column = index % mWidth;
456 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
457 int bit = column % 8;
458 int nodata = 0x80 >> bit;
460 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
475 bool setIsNoDataExcept( QRect exceptRect );
488 setIsData( static_cast< qgssize >( row )*mWidth + column );
501 if ( mHasNoDataValue )
507 if ( !mNoDataBitmap )
513 int row =
static_cast< int >( index ) / mWidth;
514 int column = index % mWidth;
515 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
516 int bit = column % 8;
517 int nodata = 0x80 >> bit;
518 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
530 QByteArray data()
const;
541 void setData(
const QByteArray &data,
int offset = 0 );
549 char *bits(
int row,
int column )
SIP_SKIP;
569 static QString printValue(
double value );
579 static QString printValue(
float value )
SIP_SKIP;
591 QImage image()
const;
597 bool setImage(
const QImage *image );
611 void applyScaleOffset(
double scale,
double offset );
619 QString toString()
const;
638 int width()
const {
return mWidth; }
657 static bool isNoDataValue(
double value,
double noDataValue )
662 return std::isnan( value ) ||
671 bool isNoDataValue(
double value )
const;
677 bool createNoDataBitmap();
706 bool mHasNoDataValue =
false;
711 static const QRgb NO_DATA_COLOR;
715 void *mData =
nullptr;
718 QImage *mImage =
nullptr;
723 char *mNoDataBitmap =
nullptr;
726 int mNoDataBitmapWidth = 0;
739 return std::numeric_limits<double>::quiet_NaN();
745 return static_cast< double >( (
static_cast< quint8 *
>( data ) )[index] );
747 return static_cast< double >( (
static_cast< quint16 *
>( data ) )[index] );
749 return static_cast< double >( (
static_cast< qint16 *
>( data ) )[index] );
751 return static_cast< double >( (
static_cast< quint32 *
>( data ) )[index] );
753 return static_cast< double >( (
static_cast< qint32 *
>( data ) )[index] );
755 return static_cast< double >( (
static_cast< float *
>( data ) )[index] );
757 return static_cast< double >( (
static_cast< double *
>( data ) )[index] );
759 QgsDebugMsg( QStringLiteral(
"Data type %1 is not supported" ).arg( type ) );
763 return std::numeric_limits<double>::quiet_NaN();
773 (
static_cast< quint8 *
>( data ) )[index] =
static_cast< quint8
>( value );
776 (
static_cast< quint16 *
>( data ) )[index] =
static_cast< quint16
>( value );
779 (
static_cast< qint16 *
>( data ) )[index] =
static_cast< qint16
>( value );
782 (
static_cast< quint32 *
>( data ) )[index] =
static_cast< quint32
>( value );
785 (
static_cast< qint32 *
>( data ) )[index] =
static_cast< qint32
>( value );
788 (
static_cast< float *
>( data ) )[index] =
static_cast< float >( value );
791 (
static_cast< double *
>( data ) )[index] = value;
794 QgsDebugMsg( QStringLiteral(
"Data type %1 is not supported" ).arg( type ) );
803 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
804 return std::numeric_limits<double>::quiet_NaN();
806 return readValue( mData, mDataType, index );
813 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
815 return std::numeric_limits<double>::quiet_NaN();
817 if ( index >= static_cast< qgssize >( mWidth )*mHeight )
819 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
821 return std::numeric_limits<double>::quiet_NaN();
824 const double val = readValue( mData, mDataType, index );
826 if ( !mHasNoDataValue && !mNoDataBitmap )
832 if ( mHasNoDataValue )
834 isNoData = isNoDataValue( val );
838 if ( !mNoDataBitmap )
850 inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP 852 return std::isnan( value ) ||
qgsDoubleNear( value, mNoDataValue );
A rectangle specified with double values.
bool isNoData(qgssize row, qgssize column) const
Check if value at position is no data.
Thirty two bit signed integer (qint32)
bool isValid() const
Returns true if the block is valid (correctly filled with data).
static double readValue(void *data, Qgis::DataType type, qgssize index)
Qgis::DataType dataType() const
Returns data type.
bool setValue(int row, int column, double value)
Set value on position.
int height() const
Returns the height (number of rows) of the raster block.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
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.
Thirty two bit unsigned integer (quint32)
QRgb * colorData()
Gives direct read/write access to the raster RGB data.
DataType
Raster data types.
bool setColor(qgssize index, QRgb color)
Set color on index (indexed line by line)
Thirty two bit floating point (float)
bool isNoData(qgssize index) const
Check if value at position is no data.
Sixteen bit signed integer (qint16)
Sixty four bit floating point (double)
QgsError error() const
Returns the last error.
bool setIsNoData(int row, int column)
Set no data on pixel.
bool setColor(int row, int column, QRgb color)
Set color on position.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
void setIsData(qgssize index)
Remove no data flag on pixel.
const quint8 * byteData() const
Gives direct access to the raster block data.
void setError(const QgsError &error)
Sets the last error.
bool setIsNoData(qgssize index)
Set no data on pixel.
QRgb color(int row, int column) const
Read a single color.
void setIsData(int row, int column)
Remove no data flag on pixel.
Unknown or unspecified type.
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
bool isNoData(int row, int column) const
Checks if value at position is no data.
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...
int width() const
Returns the width (number of columns) of the raster block.
void setValid(bool valid)
Mark block as valid or invalid.
QRgb color(qgssize index) const
Read a single value.
static void writeValue(void *data, Qgis::DataType type, qgssize index, double value)
QList< QgsRasterRange > QgsRasterRangeList
bool setValue(qgssize index, double value)
Set value on index (indexed line by line)
QgsError is container for error messages (report).
double value(int row, int column) const
Read a single value if type of block is numeric.
bool hasNoDataValue() const
true if the block has no data value.
bool hasNoData() const
Returns true if the block may contain no data.
double noDataValue() const
Returns no data value.
Eight bit unsigned integer (quint8)
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.