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 );
711 if ( rangeList.isEmpty() )
719 double val =
value( i );
743 mImage =
new QImage( *image );
748 mNoDataValue = std::numeric_limits<double>::quiet_NaN();
778 for (
int i = 15; i <= 17; i++ )
780 s.setNum( value,
'g', i );
781 if ( s.toDouble() ==
value )
787 QgsDebugMsg(
"Cannot correctly parse printed value" );
793 int destDataTypeSize =
typeSize( destDataType );
794 void *destData =
qgsMalloc( destDataTypeSize * size );
798 writeValue( destData, destDataType, i, value );
809 ba.resize((
int )size );
810 char * data = ba.data();
818 switch ( theDataType )
821 uc = ( quint8 )theValue;
822 memcpy( data, &uc, size );
825 us = ( quint16 )theValue;
826 memcpy( data, &us, size );
829 s = ( qint16 )theValue;
830 memcpy( data, &s, size );
833 ui = ( quint32 )theValue;
834 memcpy( data, &ui, size );
837 i = ( qint32 )theValue;
838 memcpy( data, &i, size );
841 f = ( float )theValue;
842 memcpy( data, &f, size );
845 d = ( double )theValue;
846 memcpy( data, &d, size );
873 double xRes = theExtent.
width() / theWidth;
874 double yRes = theExtent.
height() / theHeight;
876 QgsDebugMsg( QString(
"theWidth = %1 theHeight = %2 xRes = %3 yRes = %4" ).arg( theWidth ).arg( theHeight ).arg( xRes ).arg( yRes ) );
879 int bottom = theHeight - 1;
881 int right = theWidth - 1;
889 bottom = qRound(( theExtent.
yMaximum() - theSubExtent.
yMinimum() ) / yRes ) - 1;
898 right = qRound(( theSubExtent.
xMaximum() - theExtent.
xMinimum() ) / xRes ) - 1;
900 QRect
subRect = QRect( left, top, right - left + 1, bottom - top + 1 );
901 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
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.