31 , mDataType(
QGis::UnknownDataType )
35 , mHasNoDataValue( false )
36 , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
40 , mNoDataBitmapWidth( 0 )
41 , mNoDataBitmapSize( 0 )
47 , mDataType( theDataType )
50 , mHeight( theHeight )
51 , mHasNoDataValue( false )
52 , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
56 , mNoDataBitmapWidth( 0 )
57 , mNoDataBitmapSize( 0 )
64 , mDataType( theDataType )
67 , mHeight( theHeight )
68 , mHasNoDataValue( true )
69 , mNoDataValue( theNoDataValue )
73 , mNoDataBitmapWidth( 0 )
74 , mNoDataBitmapSize( 0 )
89 QgsDebugMsg( QString(
"theWidth= %1 theHeight = %2 theDataType = %3" ).arg( theWidth ).arg( theHeight ).arg( theDataType ) );
90 if ( !
reset( theDataType, theWidth, theHeight, std::numeric_limits<double>::quiet_NaN() ) )
101 QgsDebugMsg( QString(
"theWidth= %1 theHeight = %2 theDataType = %3 theNoDataValue = %4" ).arg( theWidth ).arg( theHeight ).arg( theDataType ).arg( theNoDataValue ) );
114 mNoDataValue = std::numeric_limits<double>::quiet_NaN();
121 QgsDebugMsg( QString(
"allocate %1 bytes" ).arg( tSize * theWidth * theHeight ) );
125 QgsDebugMsg( QString(
"Couldn't allocate data memory of %1 bytes" ).arg( tSize * theWidth * theHeight ) );
132 QImage::Format format =
imageFormat( theDataType );
133 mImage =
new QImage( theWidth, theHeight, format );
156 return QImage::Format_ARGB32;
160 return QImage::Format_ARGB32_Premultiplied;
162 return QImage::Format_Invalid;
167 if ( theFormat == QImage::Format_ARGB32 )
171 else if ( theFormat == QImage::Format_ARGB32_Premultiplied )
247 *noDataValue = -32768.0;
251 *noDataValue = -2147483648.0;
255 *noDataValue = -2147483648.0;
265 QgsDebugMsg( QString(
"Unknow data type %1" ).arg( dataType ) );
269 QgsDebugMsg( QString(
"newDataType = %1 noDataValue = %2" ).arg( newDataType ).arg( *noDataValue ) );
283 if ( qIsNaN( value ) ||
298 int row = floor((
double )index /
mWidth );
299 int column = index %
mWidth;
300 return color( row, column );
307 return mImage->pixel( column, row );
315 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg(
mWidth ).arg( mHeight ) );
330 int row = ( int ) index /
mWidth;
331 int column = index %
mWidth;
333 int bit = column % 8;
334 int mask = 0x80 >> bit;
354 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg(
mWidth ).arg( mHeight ) );
381 QgsDebugMsg( QString(
"index %1 out of range" ).arg( index ) );
412 int row = ( int ) index /
mWidth;
413 int column = index %
mWidth;
415 int bit = column % 8;
416 int nodata = 0x80 >> bit;
440 char *nodata = noDataByteArray.data();
443 memcpy((
char* )
mData + i*dataTypeSize, nodata, dataTypeSize );
477 int top = theExceptRect.top();
478 int bottom = theExceptRect.bottom();
479 int left = theExceptRect.left();
480 int right = theExceptRect.right();
481 top = qMin( qMax( top, 0 ),
mHeight - 1 );
482 left = qMin( qMax( left, 0 ),
mWidth - 1 );
483 bottom = qMax( 0, qMin( bottom,
mHeight - 1 ) );
484 right = qMax( 0, qMin( right,
mWidth - 1 ) );
501 char *nodata = noDataByteArray.data();
503 for (
int c = 0; c <
mWidth; c++ )
505 memcpy( nodataRow + c*dataTypeSize, nodata, dataTypeSize );
509 for (
int r = 0; r <
mHeight; r++ )
511 if ( r >= top && r <= bottom )
continue;
513 memcpy((
char* )
mData + i*dataTypeSize, nodataRow, dataTypeSize*mWidth );
516 for (
int r = top; r <= bottom; r++ )
520 memcpy((
char* )
mData + i*dataTypeSize, nodataRow, dataTypeSize*left );
523 int w = mWidth - right - 1;
524 memcpy((
char* )
mData + i*dataTypeSize, nodataRow, dataTypeSize*w );
543 for (
int c = 0; c <
mWidth; c ++ )
547 char nodata = 0x80 >> bit;
548 memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
552 for (
int r = 0; r <
mHeight; r++ )
554 if ( r >= top && r <= bottom )
continue;
560 for (
int c = 0; c <
mWidth; c ++ )
562 if ( c >= left && c <= right )
continue;
565 char nodata = 0x80 >> bit;
566 memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
568 for (
int r = top; r <= bottom; r++ )
595 if (
mImage->depth() != 32 )
602 QRgb *nodataRow =
new QRgb[
mWidth];
603 int rgbSize =
sizeof( QRgb );
604 for (
int c = 0; c <
mWidth; c ++ )
606 nodataRow[c] = nodataRgba;
610 for (
int r = 0; r <
mHeight; r++ )
612 if ( r >= top && r <= bottom )
continue;
614 memcpy((
void * )(
mImage->bits() + rgbSize*i ), nodataRow, rgbSize*mWidth );
617 for (
int r = top; r <= bottom; r++ )
623 memcpy((
void * )(
mImage->bits() + rgbSize*i ), nodataRow, rgbSize*( left - 1 ) );
627 int w = mWidth - right - 1;
628 memcpy((
void * )(
mImage->bits() + rgbSize*i ), nodataRow, rgbSize*w );
640 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg(
mWidth ).arg( mHeight ) );
649 return (
char* )(
mImage->bits() + index * 4 );
664 return (
char* )
mData;
668 return (
char* )(
mImage->bits() );
677 if ( destDataType ==
mDataType )
return true;
695 QImage::Format format =
imageFormat( destDataType );
713 if ( scale == 1.0 && offset == 0.0 )
return;
725 if ( rangeList.isEmpty() )
733 double val =
value( i );
757 mImage =
new QImage( *image );
762 mNoDataValue = std::numeric_limits<double>::quiet_NaN();
792 for (
int i = 15; i <= 17; i++ )
794 s.setNum( value,
'g', i );
795 if ( s.toDouble() ==
value )
801 QgsDebugMsg(
"Cannot correctly parse printed value" );
807 int destDataTypeSize =
typeSize( destDataType );
808 void *destData =
qgsMalloc( destDataTypeSize * size );
812 writeValue( destData, destDataType, i, value );
823 ba.resize((
int )size );
824 char * data = ba.data();
832 switch ( theDataType )
835 uc = ( quint8 )theValue;
836 memcpy( data, &uc, size );
839 us = ( quint16 )theValue;
840 memcpy( data, &us, size );
843 s = ( qint16 )theValue;
844 memcpy( data, &s, size );
847 ui = ( quint32 )theValue;
848 memcpy( data, &ui, size );
851 i = ( qint32 )theValue;
852 memcpy( data, &i, size );
855 f = ( float )theValue;
856 memcpy( data, &f, size );
859 d = ( double )theValue;
860 memcpy( data, &d, size );
887 double xRes = theExtent.
width() / theWidth;
888 double yRes = theExtent.
height() / theHeight;
890 QgsDebugMsg( QString(
"theWidth = %1 theHeight = %2 xRes = %3 yRes = %4" ).arg( theWidth ).arg( theHeight ).arg( xRes ).arg( yRes ) );
893 int bottom = theHeight - 1;
895 int right = theWidth - 1;
903 bottom = qRound(( theExtent.
yMaximum() - theSubExtent.
yMinimum() ) / yRes ) - 1;
912 right = qRound(( theSubExtent.
xMaximum() - theExtent.
xMinimum() ) / xRes ) - 1;
914 QRect
subRect = QRect( left, top, right - left + 1, bottom - top + 1 );
915 QgsDebugMsg( QString(
"subRect: %1 %2 %3 %4" ).arg( subRect.x() ).arg( subRect.y() ).arg( subRect.width() ).arg( subRect.height() ) );
static QImage::Format imageFormat(QGis::DataType theDataType)
static const QRgb mNoDataColor
A rectangle specified with double values.
bool convert(QGis::DataType destDataType)
Convert data to different type.
static QString printValue(double value)
Print double value with all necessary significant digits.
void * qgsMalloc(size_t size)
Allocates size bytes and returns a pointer to the allocated memory.
bool setIsNoData()
Set the whole block to no data.
static bool contains(double value, const QgsRasterRangeList &rangeList)
Test if value is within the list of ranges.
double yMaximum() const
Get the y maximum value (top side of rectangle)
static bool typeIsNumeric(QGis::DataType type)
Returns true if data type is numeric.
void applyNoDataValues(const QgsRasterRangeList &rangeList)
bool setValue(int row, int column, double value)
Set value on position.
QGis::DataType dataType() const
Returns data type.
The QGis class provides global constants for use throughout the application.
bool isNoData(int row, int column)
Check if value at position is no data.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
double ANALYSIS_EXPORT max(double x, double y)
returns the maximum of two doubles or the first argument if both are equal
bool setColor(int row, int column, QRgb color)
Set color on position.
virtual ~QgsRasterBlock()
static QGis::DataType typeWithNoDataValue(QGis::DataType dataType, double *noDataValue)
For given data type returns wider type and sets no data value.
bool setIsNoDataExcept(const QRect &theExceptRect)
Set the whole block to no data except specified rectangle.
bool hasNoData() const
Returns true if the block may contain no data.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
bool setImage(const QImage *image)
set image.
double value(int row, int column) const
Read a single value if type of block is numeric.
static bool isNoDataValue(double value, double noDataValue)
Test if value is nodata comparing to noDataValue.
static bool typeIsColor(QGis::DataType type)
Returns true if data type is color.
char * bits()
Get pointer to data.
static int typeSize(int dataType)
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 reset(QGis::DataType theDataType, int theWidth, int theHeight)
Reset block.
static void writeValue(void *data, QGis::DataType type, qgssize index, double value)
QList< QgsRasterRange > QgsRasterRangeList
void applyScaleOffset(double scale, double offset)
apply band scale and offset to raster block values @note added in 2.3
static QByteArray valueBytes(QGis::DataType theDataType, double theValue)
Get byte array representing a value.
DataType
Raster data types.
QImage image() const
Get image if type is color.
qgssize mNoDataBitmapSize
QRgb color(int row, int column) const
Read a single color.
static double readValue(void *data, QGis::DataType type, qgssize index)
bool createNoDataBitmap()
Allocate no data bitmap.
static QRect subRect(const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent)
For theExtent and theWidht, theHeight find rectangle covered by subextent.
double width() const
Width of the rectangle.
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
double xMinimum() const
Get the x minimum value (left side of rectangle)
void qgsFree(void *ptr)
Frees the memory space pointed to by ptr.
double height() const
Height of the rectangle.
bool isEmpty() const
Returns true if block is empty, i.e.