QGIS API Documentation  2.99.0-Master (19b062c)
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 "qgis_sip.h"
23 #include <limits>
24 #include <QImage>
25 #include "qgis.h"
26 #include "qgserror.h"
27 #include "qgslogger.h"
28 #include "qgsrasterrange.h"
29 
30 class QgsRectangle;
31 
36 class CORE_EXPORT QgsRasterBlock
37 {
38  public:
40 
47  QgsRasterBlock( Qgis::DataType dataType, int width, int height );
48 
49  virtual ~QgsRasterBlock();
50 
58  bool reset( Qgis::DataType dataType, int width, int height );
59 
60  // TODO: consider if use isValid() at all, isEmpty() should be sufficient
61  // and works also if block is valid but empty - difference between valid and empty?
62 
68  bool isValid() const { return mValid; }
69 
71  void setValid( bool valid ) { mValid = valid; }
72 
78  bool isEmpty() const;
79 
80  // Return data type size in bytes
81  static int typeSize( int dataType )
82  {
83  // Modified and extended copy from GDAL
84  switch ( dataType )
85  {
86  case Qgis::Byte:
87  return 1;
88 
89  case Qgis::UInt16:
90  case Qgis::Int16:
91  return 2;
92 
93  case Qgis::UInt32:
94  case Qgis::Int32:
95  case Qgis::Float32:
96  case Qgis::CInt16:
97  return 4;
98 
99  case Qgis::Float64:
100  case Qgis::CInt32:
101  case Qgis::CFloat32:
102  return 8;
103 
104  case Qgis::CFloat64:
105  return 16;
106 
107  case Qgis::ARGB32:
109  return 4;
110 
111  default:
112  return 0;
113  }
114  }
115 
116  // Data type in bytes
117  int dataTypeSize() const
118  {
119  return typeSize( mDataType );
120  }
121 
123  static bool typeIsNumeric( Qgis::DataType type );
124 
126  static bool typeIsColor( Qgis::DataType type );
127 
129  Qgis::DataType dataType() const { return mDataType; }
130 
132  static Qgis::DataType typeWithNoDataValue( Qgis::DataType dataType, double *noDataValue );
133 
139  bool hasNoDataValue() const { return mHasNoDataValue; }
140 
146  bool hasNoData() const;
147 
153  void setNoDataValue( double noDataValue );
154 
161  void resetNoDataValue();
162 
169  double noDataValue() const { return mNoDataValue; }
170 
176  static QByteArray valueBytes( Qgis::DataType dataType, double value );
177 
184  double value( int row, int column ) const;
185 
191  double value( qgssize index ) const;
192 
198  QRgb color( int row, int column ) const;
199 
204  QRgb color( qgssize index ) const;
205 
211  bool isNoData( int row, int column );
212 
217  bool isNoData( qgssize index );
218 
225  bool setValue( int row, int column, double value );
226 
232  bool setValue( qgssize index, double value );
233 
240  bool setColor( int row, int column, QRgb color );
241 
247  bool setColor( qgssize index, QRgb color );
248 
254  bool setIsNoData( int row, int column );
255 
260  bool setIsNoData( qgssize index );
261 
265  bool setIsNoData();
266 
270  bool setIsNoDataExcept( QRect exceptRect );
271 
280  void setIsData( int row, int column );
281 
289  void setIsData( qgssize index );
290 
300  QByteArray data() const;
301 
311  void setData( const QByteArray &data, int offset = 0 );
312 
320  char *bits( int row, int column ) SIP_SKIP;
321 
328  char *bits( qgssize index ) SIP_SKIP;
329 
335  char *bits() SIP_SKIP;
336 
342  static QString printValue( double value );
343 
352  static QString printValue( float value ) SIP_SKIP;
353 
358  bool convert( Qgis::DataType destDataType );
359 
363  QImage image() const;
364 
369  bool setImage( const QImage *image );
370 
372  inline static double readValue( void *data, Qgis::DataType type, qgssize index ) SIP_SKIP;
373 
375  inline static void writeValue( void *data, Qgis::DataType type, qgssize index, double value ) SIP_SKIP;
376 
377  void applyNoDataValues( const QgsRasterRangeList &rangeList );
378 
383  void applyScaleOffset( double scale, double offset );
384 
386  QgsError error() const { return mError; }
387 
389  void setError( const QgsError &error ) { mError = error;}
390 
391  QString toString() const;
392 
403  static QRect subRect( const QgsRectangle &extent, int width, int height, const QgsRectangle &subExtent );
404 
410  int width() const { return mWidth; }
411 
417  int height() const { return mHeight; }
418 
419  private:
420  static QImage::Format imageFormat( Qgis::DataType dataType );
421  static Qgis::DataType dataType( QImage::Format format );
422 
428  static bool isNoDataValue( double value, double noDataValue );
429 
434  bool isNoDataValue( double value ) const;
435 
439  bool createNoDataBitmap();
440 
449  static void *convert( void *srcData, Qgis::DataType srcDataType, Qgis::DataType destDataType, qgssize size );
450 
451  // Valid
452  bool mValid = true;
453 
454  // Data type
456 
457  // Data type size in bytes, to make bits() fast
458  int mTypeSize = 0;
459 
460  // Width
461  int mWidth = 0;
462 
463  // Height
464  int mHeight = 0;
465 
466  // Has no data value
467  bool mHasNoDataValue = false;
468 
469  // No data value
470  double mNoDataValue;
471 
472  static const QRgb NO_DATA_COLOR;
473 
474  // Data block for numerical data types, not used with image data types
475  // QByteArray does not seem to be intended for large data blocks, does it?
476  void *mData = nullptr;
477 
478  // Image for image data types, not used with numerical data types
479  QImage *mImage = nullptr;
480 
481  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
482  // Each row is represented by whole number of bytes (last bits may be unused)
483  // to make processing rows easy.
484  char *mNoDataBitmap = nullptr;
485 
486  // number of bytes in mNoDataBitmap row
487  int mNoDataBitmapWidth = 0;
488 
489  // total size in bytes of mNoDataBitmap
490  qgssize mNoDataBitmapSize = 0;
491 
492  // Error
493  QgsError mError;
494 };
495 
496 inline double QgsRasterBlock::readValue( void *data, Qgis::DataType type, qgssize index ) SIP_SKIP
497 {
498  if ( !data )
499  {
500  return std::numeric_limits<double>::quiet_NaN();
501  }
502 
503  switch ( type )
504  {
505  case Qgis::Byte:
506  return static_cast< double >( ( static_cast< quint8 * >( data ) )[index] );
507  break;
508  case Qgis::UInt16:
509  return static_cast< double >( ( static_cast< quint16 * >( data ) )[index] );
510  break;
511  case Qgis::Int16:
512  return static_cast< double >( ( static_cast< qint16 * >( data ) )[index] );
513  break;
514  case Qgis::UInt32:
515  return static_cast< double >( ( static_cast< quint32 * >( data ) )[index] );
516  break;
517  case Qgis::Int32:
518  return static_cast< double >( ( static_cast< qint32 * >( data ) )[index] );
519  break;
520  case Qgis::Float32:
521  return static_cast< double >( ( static_cast< float * >( data ) )[index] );
522  break;
523  case Qgis::Float64:
524  return static_cast< double >( ( static_cast< double * >( data ) )[index] );
525  break;
526  default:
527  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
528  break;
529  }
530 
531  return std::numeric_limits<double>::quiet_NaN();
532 }
533 
534 inline void QgsRasterBlock::writeValue( void *data, Qgis::DataType type, qgssize index, double value ) SIP_SKIP
535 {
536  if ( !data ) return;
537 
538  switch ( type )
539  {
540  case Qgis::Byte:
541  ( static_cast< quint8 * >( data ) )[index] = static_cast< quint8 >( value );
542  break;
543  case Qgis::UInt16:
544  ( static_cast< quint16 * >( data ) )[index] = static_cast< quint16 >( value );
545  break;
546  case Qgis::Int16:
547  ( static_cast< qint16 * >( data ) )[index] = static_cast< qint16 >( value );
548  break;
549  case Qgis::UInt32:
550  ( static_cast< quint32 * >( data ) )[index] = static_cast< quint32 >( value );
551  break;
552  case Qgis::Int32:
553  ( static_cast< qint32 * >( data ) )[index] = static_cast< qint32 >( value );
554  break;
555  case Qgis::Float32:
556  ( static_cast< float * >( data ) )[index] = static_cast< float >( value );
557  break;
558  case Qgis::Float64:
559  ( static_cast< double * >( data ) )[index] = value;
560  break;
561  default:
562  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
563  break;
564  }
565 }
566 
567 inline double QgsRasterBlock::value( qgssize index ) const SIP_SKIP
568 {
569  if ( !mData )
570  {
571  QgsDebugMsg( "Data block not allocated" );
572  return std::numeric_limits<double>::quiet_NaN();
573  }
574  return readValue( mData, mDataType, index );
575 }
576 
577 inline bool QgsRasterBlock::isNoDataValue( double value ) const SIP_SKIP
578 {
579  return std::isnan( value ) || qgsDoubleNear( value, mNoDataValue );
580 }
581 
582 #endif
583 
584 
A rectangle specified with double values.
Definition: qgsrectangle.h:39
Thirty two bit signed integer (qint32)
Definition: qgis.h:85
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:37
int height() const
Returns the height (number of rows) of the raster block.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:84
DataType
Raster data types.
Definition: qgis.h:78
Thirty two bit floating point (float)
Definition: qgis.h:86
Sixteen bit signed integer (qint16)
Definition: qgis.h:83
Complex Int16.
Definition: qgis.h:88
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:227
Sixty four bit floating point (double)
Definition: qgis.h:87
QgsError error() const
Get error.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:93
Raster data container.
#define SIP_SKIP
Definition: qgis_sip.h:119
void setError(const QgsError &error)
Set error.
Complex Float32.
Definition: qgis.h:90
Unknown or unspecified type.
Definition: qgis.h:80
Complex Int32.
Definition: qgis.h:89
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:82
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:452
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:83
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:91
double noDataValue() const
Return no data value.
Eight bit unsigned integer (quint8)
Definition: qgis.h:81
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition: qgis.h:92