QGIS API Documentation  2.99.0-Master (0a63d1f)
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 
45  QgsRasterBlock( Qgis::DataType theDataType, int theWidth, int theHeight );
46 
53  QgsRasterBlock( Qgis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
54 
55  virtual ~QgsRasterBlock();
56 
64  bool reset( Qgis::DataType theDataType, int theWidth, int theHeight );
65 
73  bool reset( Qgis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
74 
75  // TODO: consider if use isValid() at all, isEmpty() should be sufficient
76  // and works also if block is valid but empty - difference between valid and empty?
77 
82  bool isValid() const { return mValid; }
83 
85  void setValid( bool valid ) { mValid = valid; }
86 
91  bool isEmpty() const;
92 
93  // Return data type size in bytes
94  static int typeSize( int dataType )
95  {
96  // Modified and extended copy from GDAL
97  switch ( dataType )
98  {
99  case Qgis::Byte:
100  return 1;
101 
102  case Qgis::UInt16:
103  case Qgis::Int16:
104  return 2;
105 
106  case Qgis::UInt32:
107  case Qgis::Int32:
108  case Qgis::Float32:
109  case Qgis::CInt16:
110  return 4;
111 
112  case Qgis::Float64:
113  case Qgis::CInt32:
114  case Qgis::CFloat32:
115  return 8;
116 
117  case Qgis::CFloat64:
118  return 16;
119 
120  case Qgis::ARGB32:
122  return 4;
123 
124  default:
125  return 0;
126  }
127  }
128 
129  // Data type in bytes
130  int dataTypeSize() const
131  {
132  return typeSize( mDataType );
133  }
134 
136  static bool typeIsNumeric( Qgis::DataType type );
137 
139  static bool typeIsColor( Qgis::DataType type );
140 
142  Qgis::DataType dataType() const { return mDataType; }
143 
145  static Qgis::DataType typeWithNoDataValue( Qgis::DataType dataType, double *noDataValue );
146 
149  bool hasNoDataValue() const { return mHasNoDataValue; }
150 
155  bool hasNoData() const;
156 
160  double noDataValue() const { return mNoDataValue; }
161 
166  static QByteArray valueBytes( Qgis::DataType theDataType, double theValue );
167 
173  double value( int row, int column ) const;
174 
179  double value( qgssize index ) const;
180 
185  QRgb color( int row, int column ) const;
186 
190  QRgb color( qgssize index ) const;
191 
196  bool isNoData( int row, int column );
197 
201  bool isNoData( qgssize index );
202 
208  bool setValue( int row, int column, double value );
209 
214  bool setValue( qgssize index, double value );
215 
221  bool setColor( int row, int column, QRgb color );
222 
227  bool setColor( qgssize index, QRgb color );
228 
233  bool setIsNoData( int row, int column );
234 
238  bool setIsNoData( qgssize index );
239 
242  bool setIsNoData();
243 
246  bool setIsNoDataExcept( QRect theExceptRect );
247 
255  void setIsData( int row, int column );
256 
263  void setIsData( qgssize index );
264 
271  char * bits( int row, int column );
272 
278  char * bits( qgssize index );
279 
284  char * bits();
285 
290  static QString printValue( double value );
291 
299  static QString printValue( float value );
300 
304  bool convert( Qgis::DataType destDataType );
305 
308  QImage image() const;
309 
313  bool setImage( const QImage * image );
314 
316  inline static double readValue( void *data, Qgis::DataType type, qgssize index );
317 
319  inline static void writeValue( void *data, Qgis::DataType type, qgssize index, double value );
320 
321  void applyNoDataValues( const QgsRasterRangeList & rangeList );
322 
325  void applyScaleOffset( double scale, double offset );
326 
328  QgsError error() const { return mError; }
329 
331  void setError( const QgsError & theError ) { mError = theError;}
332 
333  QString toString() const;
334 
344  static QRect subRect( const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent );
345 
350  int width() const { return mWidth; }
351 
356  int height() const { return mHeight; }
357 
358  private:
359  static QImage::Format imageFormat( Qgis::DataType theDataType );
360  static Qgis::DataType dataType( QImage::Format theFormat );
361 
366  static bool isNoDataValue( double value, double noDataValue );
367 
371  bool isNoDataValue( double value ) const;
372 
375  bool createNoDataBitmap();
376 
384  static void * convert( void *srcData, Qgis::DataType srcDataType, Qgis::DataType destDataType, qgssize size );
385 
386  // Valid
387  bool mValid;
388 
389  // Data type
390  Qgis::DataType mDataType;
391 
392  // Data type size in bytes, to make bits() fast
393  int mTypeSize;
394 
395  // Width
396  int mWidth;
397 
398  // Height
399  int mHeight;
400 
401  // Has no data value
402  bool mHasNoDataValue;
403 
404  // No data value
405  double mNoDataValue;
406 
407  static const QRgb NO_DATA_COLOR;
408 
409  // Data block for numerical data types, not used with image data types
410  // QByteArray does not seem to be intended for large data blocks, does it?
411  void * mData;
412 
413  // Image for image data types, not used with numerical data types
414  QImage *mImage;
415 
416  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
417  // Each row is represented by whole number of bytes (last bits may be unused)
418  // to make processing rows easy.
419  char *mNoDataBitmap;
420 
421  // number of bytes in mNoDataBitmap row
422  int mNoDataBitmapWidth;
423 
424  // total size in bytes of mNoDataBitmap
425  qgssize mNoDataBitmapSize;
426 
427  // Error
428  QgsError mError;
429 };
430 
431 inline double QgsRasterBlock::readValue( void *data, Qgis::DataType type, qgssize index )
432 {
433  if ( !data )
434  {
435  return std::numeric_limits<double>::quiet_NaN();
436  }
437 
438  switch ( type )
439  {
440  case Qgis::Byte:
441  return static_cast< double >(( static_cast< quint8 * >( data ) )[index] );
442  break;
443  case Qgis::UInt16:
444  return static_cast< double >(( static_cast< quint16 * >( data ) )[index] );
445  break;
446  case Qgis::Int16:
447  return static_cast< double >(( static_cast< qint16 * >( data ) )[index] );
448  break;
449  case Qgis::UInt32:
450  return static_cast< double >(( static_cast< quint32 * >( data ) )[index] );
451  break;
452  case Qgis::Int32:
453  return static_cast< double >(( static_cast< qint32 * >( data ) )[index] );
454  break;
455  case Qgis::Float32:
456  return static_cast< double >(( static_cast< float * >( data ) )[index] );
457  break;
458  case Qgis::Float64:
459  return static_cast< double >(( static_cast< double * >( data ) )[index] );
460  break;
461  default:
462  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
463  break;
464  }
465 
466  return std::numeric_limits<double>::quiet_NaN();
467 }
468 
469 inline void QgsRasterBlock::writeValue( void *data, Qgis::DataType type, qgssize index, double value )
470 {
471  if ( !data ) return;
472 
473  switch ( type )
474  {
475  case Qgis::Byte:
476  ( static_cast< quint8 * >( data ) )[index] = static_cast< quint8 >( value );
477  break;
478  case Qgis::UInt16:
479  ( static_cast< quint16 * >( data ) )[index] = static_cast< quint16 >( value );
480  break;
481  case Qgis::Int16:
482  ( static_cast< qint16 * >( data ) )[index] = static_cast< qint16 >( value );
483  break;
484  case Qgis::UInt32:
485  ( static_cast< quint32 * >( data ) )[index] = static_cast< quint32 >( value );
486  break;
487  case Qgis::Int32:
488  ( static_cast< qint32 * >( data ) )[index] = static_cast< qint32 >( value );
489  break;
490  case Qgis::Float32:
491  ( static_cast< float * >( data ) )[index] = static_cast< float >( value );
492  break;
493  case Qgis::Float64:
494  ( static_cast< double * >( data ) )[index] = value;
495  break;
496  default:
497  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
498  break;
499  }
500 }
501 
502 inline double QgsRasterBlock::value( qgssize index ) const
503 {
504  if ( !mData )
505  {
506  QgsDebugMsg( "Data block not allocated" );
507  return std::numeric_limits<double>::quiet_NaN();
508  }
509  return readValue( mData, mDataType, index );
510 }
511 
512 inline bool QgsRasterBlock::isNoDataValue( double value ) const
513 {
514  return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
515 }
516 
517 #endif
518 
519 
static unsigned index
A rectangle specified with double values.
Definition: qgsrectangle.h:36
Thirty two bit signed integer (qint32)
Definition: qgis.h:68
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: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:193
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.
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:333
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