QGIS API Documentation  2.99.0-Master (cb63e82)
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 "qgis_core.h"
22 #include <limits>
23 #include <QImage>
24 #include "qgis.h"
25 #include "qgserror.h"
26 #include "qgslogger.h"
27 #include "qgsrasterrange.h"
28 
29 class QgsRectangle;
30 
34 class CORE_EXPORT QgsRasterBlock
35 {
36  public:
38 
44  QgsRasterBlock( Qgis::DataType dataType, int width, int height );
45 
46  virtual ~QgsRasterBlock();
47 
54  bool reset( Qgis::DataType dataType, int width, int height );
55 
56  // TODO: consider if use isValid() at all, isEmpty() should be sufficient
57  // and works also if block is valid but empty - difference between valid and empty?
58 
63  bool isValid() const { return mValid; }
64 
66  void setValid( bool valid ) { mValid = valid; }
67 
72  bool isEmpty() const;
73 
74  // Return data type size in bytes
75  static int typeSize( int dataType )
76  {
77  // Modified and extended copy from GDAL
78  switch ( dataType )
79  {
80  case Qgis::Byte:
81  return 1;
82 
83  case Qgis::UInt16:
84  case Qgis::Int16:
85  return 2;
86 
87  case Qgis::UInt32:
88  case Qgis::Int32:
89  case Qgis::Float32:
90  case Qgis::CInt16:
91  return 4;
92 
93  case Qgis::Float64:
94  case Qgis::CInt32:
95  case Qgis::CFloat32:
96  return 8;
97 
98  case Qgis::CFloat64:
99  return 16;
100 
101  case Qgis::ARGB32:
103  return 4;
104 
105  default:
106  return 0;
107  }
108  }
109 
110  // Data type in bytes
111  int dataTypeSize() const
112  {
113  return typeSize( mDataType );
114  }
115 
117  static bool typeIsNumeric( Qgis::DataType type );
118 
120  static bool typeIsColor( Qgis::DataType type );
121 
123  Qgis::DataType dataType() const { return mDataType; }
124 
126  static Qgis::DataType typeWithNoDataValue( Qgis::DataType dataType, double *noDataValue );
127 
132  bool hasNoDataValue() const { return mHasNoDataValue; }
133 
138  bool hasNoData() const;
139 
144  void setNoDataValue( double noDataValue );
145 
151  void resetNoDataValue();
152 
158  double noDataValue() const { return mNoDataValue; }
159 
164  static QByteArray valueBytes( Qgis::DataType dataType, double value );
165 
171  double value( int row, int column ) const;
172 
177  double value( qgssize index ) const;
178 
183  QRgb color( int row, int column ) const;
184 
188  QRgb color( qgssize index ) const;
189 
194  bool isNoData( int row, int column );
195 
199  bool isNoData( qgssize index );
200 
206  bool setValue( int row, int column, double value );
207 
212  bool setValue( qgssize index, double value );
213 
219  bool setColor( int row, int column, QRgb color );
220 
225  bool setColor( qgssize index, QRgb color );
226 
231  bool setIsNoData( int row, int column );
232 
236  bool setIsNoData( qgssize index );
237 
240  bool setIsNoData();
241 
244  bool setIsNoDataExcept( QRect exceptRect );
245 
253  void setIsData( int row, int column );
254 
261  void setIsData( qgssize index );
262 
271  QByteArray data() const;
272 
281  void setData( const QByteArray &data, int offset = 0 );
282 
289  char *bits( int row, int column );
290 
296  char *bits( qgssize index );
297 
302  char *bits();
303 
308  static QString printValue( double value );
309 
317  static QString printValue( float value );
318 
322  bool convert( Qgis::DataType destDataType );
323 
326  QImage image() const;
327 
331  bool setImage( const QImage *image );
332 
334  inline static double readValue( void *data, Qgis::DataType type, qgssize index );
335 
337  inline static void writeValue( void *data, Qgis::DataType type, qgssize index, double value );
338 
339  void applyNoDataValues( const QgsRasterRangeList &rangeList );
340 
345  void applyScaleOffset( double scale, double offset );
346 
348  QgsError error() const { return mError; }
349 
351  void setError( const QgsError &error ) { mError = error;}
352 
353  QString toString() const;
354 
364  static QRect subRect( const QgsRectangle &extent, int width, int height, const QgsRectangle &subExtent );
365 
370  int width() const { return mWidth; }
371 
376  int height() const { return mHeight; }
377 
378  private:
379  static QImage::Format imageFormat( Qgis::DataType dataType );
380  static Qgis::DataType dataType( QImage::Format format );
381 
386  static bool isNoDataValue( double value, double noDataValue );
387 
391  bool isNoDataValue( double value ) const;
392 
395  bool createNoDataBitmap();
396 
404  static void *convert( void *srcData, Qgis::DataType srcDataType, Qgis::DataType destDataType, qgssize size );
405 
406  // Valid
407  bool mValid;
408 
409  // Data type
410  Qgis::DataType mDataType;
411 
412  // Data type size in bytes, to make bits() fast
413  int mTypeSize;
414 
415  // Width
416  int mWidth;
417 
418  // Height
419  int mHeight;
420 
421  // Has no data value
422  bool mHasNoDataValue;
423 
424  // No data value
425  double mNoDataValue;
426 
427  static const QRgb NO_DATA_COLOR;
428 
429  // Data block for numerical data types, not used with image data types
430  // QByteArray does not seem to be intended for large data blocks, does it?
431  void *mData = nullptr;
432 
433  // Image for image data types, not used with numerical data types
434  QImage *mImage = nullptr;
435 
436  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
437  // Each row is represented by whole number of bytes (last bits may be unused)
438  // to make processing rows easy.
439  char *mNoDataBitmap = nullptr;
440 
441  // number of bytes in mNoDataBitmap row
442  int mNoDataBitmapWidth;
443 
444  // total size in bytes of mNoDataBitmap
445  qgssize mNoDataBitmapSize;
446 
447  // Error
448  QgsError mError;
449 };
450 
451 inline double QgsRasterBlock::readValue( void *data, Qgis::DataType type, qgssize index )
452 {
453  if ( !data )
454  {
455  return std::numeric_limits<double>::quiet_NaN();
456  }
457 
458  switch ( type )
459  {
460  case Qgis::Byte:
461  return static_cast< double >( ( static_cast< quint8 * >( data ) )[index] );
462  break;
463  case Qgis::UInt16:
464  return static_cast< double >( ( static_cast< quint16 * >( data ) )[index] );
465  break;
466  case Qgis::Int16:
467  return static_cast< double >( ( static_cast< qint16 * >( data ) )[index] );
468  break;
469  case Qgis::UInt32:
470  return static_cast< double >( ( static_cast< quint32 * >( data ) )[index] );
471  break;
472  case Qgis::Int32:
473  return static_cast< double >( ( static_cast< qint32 * >( data ) )[index] );
474  break;
475  case Qgis::Float32:
476  return static_cast< double >( ( static_cast< float * >( data ) )[index] );
477  break;
478  case Qgis::Float64:
479  return static_cast< double >( ( static_cast< double * >( data ) )[index] );
480  break;
481  default:
482  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
483  break;
484  }
485 
486  return std::numeric_limits<double>::quiet_NaN();
487 }
488 
489 inline void QgsRasterBlock::writeValue( void *data, Qgis::DataType type, qgssize index, double value )
490 {
491  if ( !data ) return;
492 
493  switch ( type )
494  {
495  case Qgis::Byte:
496  ( static_cast< quint8 * >( data ) )[index] = static_cast< quint8 >( value );
497  break;
498  case Qgis::UInt16:
499  ( static_cast< quint16 * >( data ) )[index] = static_cast< quint16 >( value );
500  break;
501  case Qgis::Int16:
502  ( static_cast< qint16 * >( data ) )[index] = static_cast< qint16 >( value );
503  break;
504  case Qgis::UInt32:
505  ( static_cast< quint32 * >( data ) )[index] = static_cast< quint32 >( value );
506  break;
507  case Qgis::Int32:
508  ( static_cast< qint32 * >( data ) )[index] = static_cast< qint32 >( value );
509  break;
510  case Qgis::Float32:
511  ( static_cast< float * >( data ) )[index] = static_cast< float >( value );
512  break;
513  case Qgis::Float64:
514  ( static_cast< double * >( data ) )[index] = value;
515  break;
516  default:
517  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
518  break;
519  }
520 }
521 
522 inline double QgsRasterBlock::value( qgssize index ) const
523 {
524  if ( !mData )
525  {
526  QgsDebugMsg( "Data block not allocated" );
527  return std::numeric_limits<double>::quiet_NaN();
528  }
529  return readValue( mData, mDataType, index );
530 }
531 
532 inline bool QgsRasterBlock::isNoDataValue( double value ) const
533 {
534  return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
535 }
536 
537 #endif
538 
539 
A rectangle specified with double values.
Definition: qgsrectangle.h:38
Thirty two bit signed integer (qint32)
Definition: qgis.h:68
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:36
int height() const
Returns the height (number of rows) of the raster block.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:67
DataType
Raster data types.
Definition: qgis.h:61
Thirty two bit floating point (float)
Definition: qgis.h:69
Sixteen bit signed integer (qint16)
Definition: qgis.h:66
Complex Int16.
Definition: qgis.h:71
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:201
Sixty four bit floating point (double)
Definition: qgis.h:70
QgsError error() const
Get error.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:76
Raster data container.
void setError(const QgsError &error)
Set error.
Complex Float32.
Definition: qgis.h:73
Complex Int32.
Definition: qgis.h:72
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:65
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:352
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:82
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:74
double noDataValue() const
Return no data value.
Eight bit unsigned integer (quint8)
Definition: qgis.h:64
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition: qgis.h:75