QGIS API Documentation  2.99.0-Master (e077efd)
qgsrasterblock.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterblock.h - Class representing a block of raster data
3  --------------------------------------
4  Date : Oct 9, 2012
5  Copyright : (C) 2012 by Radim Blazek
6  email : radim dot blazek at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef QGSRASTERBLOCK_H
19 #define QGSRASTERBLOCK_H
20 
21 #include <limits>
22 #include <QImage>
23 #include "qgis.h"
24 #include "qgserror.h"
25 #include "qgslogger.h"
26 #include "qgsrasterrange.h"
27 
28 class QgsRectangle;
29 
33 class CORE_EXPORT QgsRasterBlock
34 {
35  public:
37 
44  QgsRasterBlock( Qgis::DataType theDataType, int theWidth, int theHeight );
45 
52  QgsRasterBlock( Qgis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
53 
54  virtual ~QgsRasterBlock();
55 
63  bool reset( Qgis::DataType theDataType, int theWidth, int theHeight );
64 
72  bool reset( Qgis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
73 
74  // TODO: consider if use isValid() at all, isEmpty() should be sufficient
75  // and works also if block is valid but empty - difference between valid and empty?
76 
81  bool isValid() const { return mValid; }
82 
84  void setValid( bool valid ) { mValid = valid; }
85 
90  bool isEmpty() const;
91 
92  // Return data type size in bytes
93  static int typeSize( int dataType )
94  {
95  // Modified and extended copy from GDAL
96  switch ( dataType )
97  {
98  case Qgis::Byte:
99  return 1;
100 
101  case Qgis::UInt16:
102  case Qgis::Int16:
103  return 2;
104 
105  case Qgis::UInt32:
106  case Qgis::Int32:
107  case Qgis::Float32:
108  case Qgis::CInt16:
109  return 4;
110 
111  case Qgis::Float64:
112  case Qgis::CInt32:
113  case Qgis::CFloat32:
114  return 8;
115 
116  case Qgis::CFloat64:
117  return 16;
118 
119  case Qgis::ARGB32:
121  return 4;
122 
123  default:
124  return 0;
125  }
126  }
127 
128  // Data type in bytes
129  int dataTypeSize() const
130  {
131  return typeSize( mDataType );
132  }
133 
135  static bool typeIsNumeric( Qgis::DataType type );
136 
138  static bool typeIsColor( Qgis::DataType type );
139 
141  Qgis::DataType dataType() const { return mDataType; }
142 
144  static Qgis::DataType typeWithNoDataValue( Qgis::DataType dataType, double *noDataValue );
145 
148  bool hasNoDataValue() const { return mHasNoDataValue; }
149 
154  bool hasNoData() const;
155 
159  double noDataValue() const { return mNoDataValue; }
160 
165  static QByteArray valueBytes( Qgis::DataType theDataType, double theValue );
166 
172  double value( int row, int column ) const;
173 
178  double value( qgssize index ) const;
179 
184  QRgb color( int row, int column ) const;
185 
189  QRgb color( qgssize index ) const;
190 
195  bool isNoData( int row, int column );
196 
200  bool isNoData( qgssize index );
201 
207  bool setValue( int row, int column, double value );
208 
213  bool setValue( qgssize index, double value );
214 
220  bool setColor( int row, int column, QRgb color );
221 
226  bool setColor( qgssize index, QRgb color );
227 
232  bool setIsNoData( int row, int column );
233 
237  bool setIsNoData( qgssize index );
238 
241  bool setIsNoData();
242 
245  bool setIsNoDataExcept( QRect theExceptRect );
246 
254  void setIsData( int row, int column );
255 
262  void setIsData( qgssize index );
263 
270  char * bits( int row, int column );
271 
277  char * bits( qgssize index );
278 
283  char * bits();
284 
289  static QString printValue( double value );
290 
298  static QString printValue( float value );
299 
303  bool convert( Qgis::DataType destDataType );
304 
307  QImage image() const;
308 
312  bool setImage( const QImage * image );
313 
315  inline static double readValue( void *data, Qgis::DataType type, qgssize index );
316 
318  inline static void writeValue( void *data, Qgis::DataType type, qgssize index, double value );
319 
320  void applyNoDataValues( const QgsRasterRangeList & rangeList );
321 
324  void applyScaleOffset( double scale, double offset );
325 
327  QgsError error() const { return mError; }
328 
330  void setError( const QgsError & theError ) { mError = theError;}
331 
332  QString toString() const;
333 
343  static QRect subRect( const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent );
344 
349  int width() const { return mWidth; }
350 
355  int height() const { return mHeight; }
356 
357  private:
358  static QImage::Format imageFormat( Qgis::DataType theDataType );
359  static Qgis::DataType dataType( QImage::Format theFormat );
360 
365  static bool isNoDataValue( double value, double noDataValue );
366 
370  bool isNoDataValue( double value ) const;
371 
374  bool createNoDataBitmap();
375 
383  static void * convert( void *srcData, Qgis::DataType srcDataType, Qgis::DataType destDataType, qgssize size );
384 
385  // Valid
386  bool mValid;
387 
388  // Data type
389  Qgis::DataType mDataType;
390 
391  // Data type size in bytes, to make bits() fast
392  int mTypeSize;
393 
394  // Width
395  int mWidth;
396 
397  // Height
398  int mHeight;
399 
400  // Has no data value
401  bool mHasNoDataValue;
402 
403  // No data value
404  double mNoDataValue;
405 
406  static const QRgb mNoDataColor;
407 
408  // Data block for numerical data types, not used with image data types
409  // QByteArray does not seem to be intended for large data blocks, does it?
410  void * mData;
411 
412  // Image for image data types, not used with numerical data types
413  QImage *mImage;
414 
415  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
416  // Each row is represented by whole number of bytes (last bits may be unused)
417  // to make processing rows easy.
418  char *mNoDataBitmap;
419 
420  // number of bytes in mNoDataBitmap row
421  int mNoDataBitmapWidth;
422 
423  // total size in bytes of mNoDataBitmap
424  qgssize mNoDataBitmapSize;
425 
426  // Error
427  QgsError mError;
428 };
429 
430 inline double QgsRasterBlock::readValue( void *data, Qgis::DataType type, qgssize index )
431 {
432  if ( !data )
433  {
434  return std::numeric_limits<double>::quiet_NaN();
435  }
436 
437  switch ( type )
438  {
439  case Qgis::Byte:
440  return static_cast< double >(( static_cast< quint8 * >( data ) )[index] );
441  break;
442  case Qgis::UInt16:
443  return static_cast< double >(( static_cast< quint16 * >( data ) )[index] );
444  break;
445  case Qgis::Int16:
446  return static_cast< double >(( static_cast< qint16 * >( data ) )[index] );
447  break;
448  case Qgis::UInt32:
449  return static_cast< double >(( static_cast< quint32 * >( data ) )[index] );
450  break;
451  case Qgis::Int32:
452  return static_cast< double >(( static_cast< qint32 * >( data ) )[index] );
453  break;
454  case Qgis::Float32:
455  return static_cast< double >(( static_cast< float * >( data ) )[index] );
456  break;
457  case Qgis::Float64:
458  return static_cast< double >(( static_cast< double * >( data ) )[index] );
459  break;
460  default:
461  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
462  break;
463  }
464 
465  return std::numeric_limits<double>::quiet_NaN();
466 }
467 
468 inline void QgsRasterBlock::writeValue( void *data, Qgis::DataType type, qgssize index, double value )
469 {
470  if ( !data ) return;
471 
472  switch ( type )
473  {
474  case Qgis::Byte:
475  ( static_cast< quint8 * >( data ) )[index] = static_cast< quint8 >( value );
476  break;
477  case Qgis::UInt16:
478  ( static_cast< quint16 * >( data ) )[index] = static_cast< quint16 >( value );
479  break;
480  case Qgis::Int16:
481  ( static_cast< qint16 * >( data ) )[index] = static_cast< qint16 >( value );
482  break;
483  case Qgis::UInt32:
484  ( static_cast< quint32 * >( data ) )[index] = static_cast< quint32 >( value );
485  break;
486  case Qgis::Int32:
487  ( static_cast< qint32 * >( data ) )[index] = static_cast< qint32 >( value );
488  break;
489  case Qgis::Float32:
490  ( static_cast< float * >( data ) )[index] = static_cast< float >( value );
491  break;
492  case Qgis::Float64:
493  ( static_cast< double * >( data ) )[index] = value;
494  break;
495  default:
496  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
497  break;
498  }
499 }
500 
501 inline double QgsRasterBlock::value( qgssize index ) const
502 {
503  if ( !mData )
504  {
505  QgsDebugMsg( "Data block not allocated" );
506  return std::numeric_limits<double>::quiet_NaN();
507  }
508  return readValue( mData, mDataType, index );
509 }
510 
511 inline bool QgsRasterBlock::isNoDataValue( double value ) const
512 {
513  return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
514 }
515 
516 #endif
517 
518 
static unsigned index
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Thirty two bit signed integer (qint32)
Definition: qgis.h:67
void setError(const QgsError &theError)
Set error.
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.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
int height() const
Returns the height (number of rows) of the raster block.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:66
DataType
Raster data types.
Definition: qgis.h:60
Thirty two bit floating point (float)
Definition: qgis.h:68
Sixteen bit signed integer (qint16)
Definition: qgis.h:65
Complex Int16.
Definition: qgis.h:70
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:196
Sixty four bit floating point (double)
Definition: qgis.h:69
QgsError error() const
Get error.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:75
Raster data container.
Complex Float32.
Definition: qgis.h:72
Complex Int32.
Definition: qgis.h:71
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:64
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...
Definition: qgis.h:336
int width() const
Returns the width (number of columns) of the raster block.
void setValid(bool valid)
Mark block as valid or invalid.
static void writeValue(void *data, Qgis::DataType type, qgssize index, double value)
QList< QgsRasterRange > QgsRasterRangeList
QgsError is container for error messages (report).
Definition: qgserror.h:80
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.
int dataTypeSize() const
Complex Float64.
Definition: qgis.h:73
double noDataValue() const
Return no data value.
Eight bit unsigned integer (quint8)
Definition: qgis.h:63
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition: qgis.h:74