QGIS API Documentation  2.99.0-Master (dcec6bb)
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 
35 class CORE_EXPORT QgsRasterBlock
36 {
37  public:
39 
45  QgsRasterBlock( Qgis::DataType dataType, int width, int height );
46 
47  virtual ~QgsRasterBlock();
48 
55  bool reset( Qgis::DataType dataType, int width, int height );
56 
57  // TODO: consider if use isValid() at all, isEmpty() should be sufficient
58  // and works also if block is valid but empty - difference between valid and empty?
59 
64  bool isValid() const { return mValid; }
65 
67  void setValid( bool valid ) { mValid = valid; }
68 
73  bool isEmpty() const;
74 
75  // Return data type size in bytes
76  static int typeSize( int dataType )
77  {
78  // Modified and extended copy from GDAL
79  switch ( dataType )
80  {
81  case Qgis::Byte:
82  return 1;
83 
84  case Qgis::UInt16:
85  case Qgis::Int16:
86  return 2;
87 
88  case Qgis::UInt32:
89  case Qgis::Int32:
90  case Qgis::Float32:
91  case Qgis::CInt16:
92  return 4;
93 
94  case Qgis::Float64:
95  case Qgis::CInt32:
96  case Qgis::CFloat32:
97  return 8;
98 
99  case Qgis::CFloat64:
100  return 16;
101 
102  case Qgis::ARGB32:
104  return 4;
105 
106  default:
107  return 0;
108  }
109  }
110 
111  // Data type in bytes
112  int dataTypeSize() const
113  {
114  return typeSize( mDataType );
115  }
116 
118  static bool typeIsNumeric( Qgis::DataType type );
119 
121  static bool typeIsColor( Qgis::DataType type );
122 
124  Qgis::DataType dataType() const { return mDataType; }
125 
127  static Qgis::DataType typeWithNoDataValue( Qgis::DataType dataType, double *noDataValue );
128 
133  bool hasNoDataValue() const { return mHasNoDataValue; }
134 
139  bool hasNoData() const;
140 
145  void setNoDataValue( double noDataValue );
146 
152  void resetNoDataValue();
153 
159  double noDataValue() const { return mNoDataValue; }
160 
165  static QByteArray valueBytes( Qgis::DataType dataType, double value );
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 exceptRect );
246 
254  void setIsData( int row, int column );
255 
262  void setIsData( qgssize index );
263 
272  QByteArray data() const;
273 
282  void setData( const QByteArray &data, int offset = 0 );
283 
290  char *bits( int row, int column ) SIP_SKIP;
291 
297  char *bits( qgssize index ) SIP_SKIP;
298 
303  char *bits() SIP_SKIP;
304 
309  static QString printValue( double value );
310 
318  static QString printValue( float value ) SIP_SKIP;
319 
323  bool convert( Qgis::DataType destDataType );
324 
327  QImage image() const;
328 
332  bool setImage( const QImage *image );
333 
335  inline static double readValue( void *data, Qgis::DataType type, qgssize index ) SIP_SKIP;
336 
338  inline static void writeValue( void *data, Qgis::DataType type, qgssize index, double value ) SIP_SKIP;
339 
340  void applyNoDataValues( const QgsRasterRangeList &rangeList );
341 
346  void applyScaleOffset( double scale, double offset );
347 
349  QgsError error() const { return mError; }
350 
352  void setError( const QgsError &error ) { mError = error;}
353 
354  QString toString() const;
355 
365  static QRect subRect( const QgsRectangle &extent, int width, int height, const QgsRectangle &subExtent );
366 
371  int width() const { return mWidth; }
372 
377  int height() const { return mHeight; }
378 
379  private:
380  static QImage::Format imageFormat( Qgis::DataType dataType );
381  static Qgis::DataType dataType( QImage::Format format );
382 
387  static bool isNoDataValue( double value, double noDataValue );
388 
392  bool isNoDataValue( double value ) const;
393 
396  bool createNoDataBitmap();
397 
405  static void *convert( void *srcData, Qgis::DataType srcDataType, Qgis::DataType destDataType, qgssize size );
406 
407  // Valid
408  bool mValid;
409 
410  // Data type
411  Qgis::DataType mDataType;
412 
413  // Data type size in bytes, to make bits() fast
414  int mTypeSize;
415 
416  // Width
417  int mWidth;
418 
419  // Height
420  int mHeight;
421 
422  // Has no data value
423  bool mHasNoDataValue;
424 
425  // No data value
426  double mNoDataValue;
427 
428  static const QRgb NO_DATA_COLOR;
429 
430  // Data block for numerical data types, not used with image data types
431  // QByteArray does not seem to be intended for large data blocks, does it?
432  void *mData = nullptr;
433 
434  // Image for image data types, not used with numerical data types
435  QImage *mImage = nullptr;
436 
437  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
438  // Each row is represented by whole number of bytes (last bits may be unused)
439  // to make processing rows easy.
440  char *mNoDataBitmap = nullptr;
441 
442  // number of bytes in mNoDataBitmap row
443  int mNoDataBitmapWidth;
444 
445  // total size in bytes of mNoDataBitmap
446  qgssize mNoDataBitmapSize;
447 
448  // Error
449  QgsError mError;
450 };
451 
452 inline double QgsRasterBlock::readValue( void *data, Qgis::DataType type, qgssize index ) SIP_SKIP
453 {
454  if ( !data )
455  {
456  return std::numeric_limits<double>::quiet_NaN();
457  }
458 
459  switch ( type )
460  {
461  case Qgis::Byte:
462  return static_cast< double >( ( static_cast< quint8 * >( data ) )[index] );
463  break;
464  case Qgis::UInt16:
465  return static_cast< double >( ( static_cast< quint16 * >( data ) )[index] );
466  break;
467  case Qgis::Int16:
468  return static_cast< double >( ( static_cast< qint16 * >( data ) )[index] );
469  break;
470  case Qgis::UInt32:
471  return static_cast< double >( ( static_cast< quint32 * >( data ) )[index] );
472  break;
473  case Qgis::Int32:
474  return static_cast< double >( ( static_cast< qint32 * >( data ) )[index] );
475  break;
476  case Qgis::Float32:
477  return static_cast< double >( ( static_cast< float * >( data ) )[index] );
478  break;
479  case Qgis::Float64:
480  return static_cast< double >( ( static_cast< double * >( data ) )[index] );
481  break;
482  default:
483  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
484  break;
485  }
486 
487  return std::numeric_limits<double>::quiet_NaN();
488 }
489 
490 inline void QgsRasterBlock::writeValue( void *data, Qgis::DataType type, qgssize index, double value ) SIP_SKIP
491 {
492  if ( !data ) return;
493 
494  switch ( type )
495  {
496  case Qgis::Byte:
497  ( static_cast< quint8 * >( data ) )[index] = static_cast< quint8 >( value );
498  break;
499  case Qgis::UInt16:
500  ( static_cast< quint16 * >( data ) )[index] = static_cast< quint16 >( value );
501  break;
502  case Qgis::Int16:
503  ( static_cast< qint16 * >( data ) )[index] = static_cast< qint16 >( value );
504  break;
505  case Qgis::UInt32:
506  ( static_cast< quint32 * >( data ) )[index] = static_cast< quint32 >( value );
507  break;
508  case Qgis::Int32:
509  ( static_cast< qint32 * >( data ) )[index] = static_cast< qint32 >( value );
510  break;
511  case Qgis::Float32:
512  ( static_cast< float * >( data ) )[index] = static_cast< float >( value );
513  break;
514  case Qgis::Float64:
515  ( static_cast< double * >( data ) )[index] = value;
516  break;
517  default:
518  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
519  break;
520  }
521 }
522 
523 inline double QgsRasterBlock::value( qgssize index ) const SIP_SKIP
524 {
525  if ( !mData )
526  {
527  QgsDebugMsg( "Data block not allocated" );
528  return std::numeric_limits<double>::quiet_NaN();
529  }
530  return readValue( mData, mDataType, index );
531 }
532 
533 inline bool QgsRasterBlock::isNoDataValue( double value ) const SIP_SKIP
534 {
535  return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
536 }
537 
538 #endif
539 
540 
A rectangle specified with double values.
Definition: qgsrectangle.h:38
Thirty two bit signed integer (qint32)
Definition: qgis.h:81
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:80
DataType
Raster data types.
Definition: qgis.h:74
Thirty two bit floating point (float)
Definition: qgis.h:82
Sixteen bit signed integer (qint16)
Definition: qgis.h:79
Complex Int16.
Definition: qgis.h:84
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:203
Sixty four bit floating point (double)
Definition: qgis.h:83
QgsError error() const
Get error.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:89
Raster data container.
#define SIP_SKIP
Definition: qgis_sip.h:119
void setError(const QgsError &error)
Set error.
Complex Float32.
Definition: qgis.h:86
Complex Int32.
Definition: qgis.h:85
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:78
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:348
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:87
double noDataValue() const
Return no data value.
Eight bit unsigned integer (quint8)
Definition: qgis.h:77
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition: qgis.h:88