QGIS API Documentation  master-6227475
src/core/raster/qgsrasterblock.h
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsrasterblock.h - Class representing a block of raster data
00003      --------------------------------------
00004     Date                 : Oct 9, 2012
00005     Copyright            : (C) 2012 by Radim Blazek
00006     email                : radim dot blazek at gmail dot com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #ifndef QGSRASTERBLOCK_H
00019 #define QGSRASTERBLOCK_H
00020 
00021 #include <limits>
00022 #include <QImage>
00023 #include "qgis.h"
00024 #include "qgserror.h"
00025 #include "qgslogger.h"
00026 #include "qgsrasterrange.h"
00027 #include "qgsrectangle.h"
00028 
00032 class CORE_EXPORT QgsRasterBlock
00033 {
00034   public:
00035     QgsRasterBlock();
00036 
00042     QgsRasterBlock( QGis::DataType theDataType, int theWidth, int theHeight );
00043 
00050     QgsRasterBlock( QGis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
00051 
00052     virtual ~QgsRasterBlock();
00053 
00060     bool reset( QGis::DataType theDataType, int theWidth, int theHeight );
00061 
00069     bool reset( QGis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
00070 
00071     // TODO: consider if use isValid() at all, isEmpty() should be sufficient
00072     // and works also if block is valid but empty - difference between valid and empty?
00077     bool isValid() const { return mValid; }
00078 
00080     void setValid( bool valid ) { mValid = valid; }
00081 
00086     bool isEmpty() const;
00087 
00088     // Return data type size in bytes
00089     static int typeSize( int dataType )
00090     {
00091       // Modified and extended copy from GDAL
00092       switch ( dataType )
00093       {
00094         case QGis::Byte:
00095           return 1;
00096 
00097         case QGis::UInt16:
00098         case QGis::Int16:
00099           return 2;
00100 
00101         case QGis::UInt32:
00102         case QGis::Int32:
00103         case QGis::Float32:
00104         case QGis::CInt16:
00105           return 4;
00106 
00107         case QGis::Float64:
00108         case QGis::CInt32:
00109         case QGis::CFloat32:
00110           return 8;
00111 
00112         case QGis::CFloat64:
00113           return 16;
00114 
00115         case QGis::ARGB32:
00116         case QGis::ARGB32_Premultiplied:
00117           return 4;
00118 
00119         default:
00120           return 0;
00121       }
00122     }
00123 
00124     // Data type in bytes
00125     int dataTypeSize( ) const
00126     {
00127       return typeSize( mDataType );
00128     }
00129 
00131     static bool typeIsNumeric( QGis::DataType type );
00132 
00134     static bool typeIsColor( QGis::DataType type );
00135 
00137     QGis::DataType dataType() const { return mDataType; }
00138 
00140     static QGis::DataType typeWithNoDataValue( QGis::DataType dataType, double *noDataValue );
00141 
00144     bool hasNoDataValue() const { return mHasNoDataValue; }
00145 
00150     bool hasNoData() const;
00151 
00155     double noDataValue() const { return mNoDataValue; }
00156 
00161     static QByteArray valueBytes( QGis::DataType theDataType, double theValue );
00162 
00168     double value( int row, int column ) const;
00169 
00174     double value( size_t index ) const;
00175 
00180     QRgb color( int row, int column ) const;
00181 
00185     QRgb color( size_t index ) const;
00186 
00191     bool isNoData( int row, int column );
00192 
00196     bool isNoData( size_t index );
00197 
00203     bool setValue( int row, int column, double value );
00204 
00209     bool setValue( size_t index, double value );
00210 
00216     bool setColor( int row, int column, QRgb color );
00217 
00222     bool setColor( size_t index, QRgb color );
00223 
00228     bool setIsNoData( int row, int column );
00229 
00233     bool setIsNoData( size_t index );
00234 
00237     bool setIsNoData( );
00238 
00241     bool setIsNoDataExcept( const QRect & theExceptRect );
00242 
00248     char * bits( int row, int column );
00249 
00253     char * bits( size_t index );
00254 
00257     char * bits();
00258 
00263     static QString printValue( double value );
00264 
00268     bool convert( QGis::DataType destDataType );
00269 
00272     QImage image() const;
00273 
00277     bool setImage( const QImage * image );
00278 
00279     inline static double readValue( void *data, QGis::DataType type, size_t index );
00280 
00281     inline static void writeValue( void *data, QGis::DataType type, size_t index, double value );
00282 
00283     void applyNoDataValues( const QgsRasterRangeList & rangeList );
00284 
00286     QgsError error() const { return mError; }
00287 
00289     void setError( const QgsError & theError ) { mError = theError;}
00290 
00300     static QRect subRect( const QgsRectangle & theExtent, int theWidth, int theHeight, const QgsRectangle &  theSubExtent );
00301 
00302   private:
00303     static QImage::Format imageFormat( QGis::DataType theDataType );
00304     static QGis::DataType dataType( QImage::Format theFormat );
00305 
00310     static bool isNoDataValue( double value, double noDataValue );
00311 
00315     bool isNoDataValue( double value ) const;
00316 
00319     bool createNoDataBitmap();
00320 
00328     static void * convert( void *srcData, QGis::DataType srcDataType, QGis::DataType destDataType, size_t size );
00329 
00330     // Valid
00331     bool mValid;
00332 
00333     // Data type
00334     QGis::DataType mDataType;
00335 
00336     // Data type size in bytes, to make bits() fast
00337     int mTypeSize;
00338 
00339     // Width
00340     int mWidth;
00341 
00342     // Height
00343     int mHeight;
00344 
00345     // Has no data value
00346     bool mHasNoDataValue;
00347 
00348     // No data value
00349     double mNoDataValue;
00350 
00351     // Data block for numerical data types, not used with image data types
00352     // QByteArray does not seem to be intended for large data blocks, does it?
00353     void * mData;
00354 
00355     // Image for image data types, not used with numerical data types
00356     QImage *mImage;
00357 
00358     // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
00359     // Each row is represented by whole number of bytes (last bits may be unused)
00360     // to make processing rows easy.
00361     char *mNoDataBitmap;
00362 
00363     // number of bytes in mNoDataBitmap row
00364     int mNoDataBitmapWidth;
00365 
00366     // total size in bytes of mNoDataBitmap
00367     size_t mNoDataBitmapSize;
00368 
00369     // Error
00370     QgsError mError;
00371 };
00372 
00373 inline double QgsRasterBlock::readValue( void *data, QGis::DataType type, size_t index )
00374 {
00375   if ( !data )
00376   {
00377     return std::numeric_limits<double>::quiet_NaN();
00378   }
00379 
00380   switch ( type )
00381   {
00382     case QGis::Byte:
00383       return ( double )(( quint8 * )data )[index];
00384       break;
00385     case QGis::UInt16:
00386       return ( double )(( quint16 * )data )[index];
00387       break;
00388     case QGis::Int16:
00389       return ( double )(( qint16 * )data )[index];
00390       break;
00391     case QGis::UInt32:
00392       return ( double )(( quint32 * )data )[index];
00393       break;
00394     case QGis::Int32:
00395       return ( double )(( qint32 * )data )[index];
00396       break;
00397     case QGis::Float32:
00398       return ( double )(( float * )data )[index];
00399       break;
00400     case QGis::Float64:
00401       return ( double )(( double * )data )[index];
00402       break;
00403     default:
00404       QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
00405       break;
00406   }
00407 
00408   return std::numeric_limits<double>::quiet_NaN();
00409 }
00410 
00411 inline void QgsRasterBlock::writeValue( void *data, QGis::DataType type, size_t index, double value )
00412 {
00413   if ( !data ) return;
00414 
00415   switch ( type )
00416   {
00417     case QGis::Byte:
00418       (( quint8 * )data )[index] = ( quint8 ) value;
00419       break;
00420     case QGis::UInt16:
00421       (( quint16 * )data )[index] = ( quint16 ) value;
00422       break;
00423     case QGis::Int16:
00424       (( qint16 * )data )[index] = ( qint16 ) value;
00425       break;
00426     case QGis::UInt32:
00427       (( quint32 * )data )[index] = ( quint32 ) value;
00428       break;
00429     case QGis::Int32:
00430       (( qint32 * )data )[index] = ( qint32 ) value;
00431       break;
00432     case QGis::Float32:
00433       (( float * )data )[index] = ( float ) value;
00434       break;
00435     case QGis::Float64:
00436       (( double * )data )[index] = value;
00437       break;
00438     default:
00439       QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
00440       break;
00441   }
00442 }
00443 
00444 inline double QgsRasterBlock::value( size_t index ) const
00445 {
00446   if ( !mData )
00447   {
00448     QgsDebugMsg( "Data block not allocated" );
00449     return std::numeric_limits<double>::quiet_NaN();
00450   }
00451   return readValue( mData, mDataType, index );
00452 }
00453 
00454 inline bool QgsRasterBlock::isNoDataValue( double value ) const
00455 {
00456   return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
00457 }
00458 
00459 #endif
00460 
00461 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines