Skip to content
Permalink
Browse files

raster cleanup

  • Loading branch information
blazek committed Apr 15, 2013
1 parent 2ef7e49 commit 1f65f718338f9471e6520abb165aecbc959d015d
@@ -18,7 +18,7 @@ class QgsRasterBlock

int typeSize( int dataType ) const;

int dataTypeSize( int bandNo ) const;
int dataTypeSize() const;

/** Returns true if data type is numeric */
bool typeIsNumeric( QGis::DataType type ) const;
@@ -210,7 +210,7 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con

//use direct data access instead of QgsRasterBlock::setValue
//because of performance
unsigned int* outputData = ( unsigned int* )( outputBlock->data() );
unsigned int* outputData = ( unsigned int* )( outputBlock->bits() );

size_t rasterSize = ( size_t )width * height;
for ( size_t i = 0; i < rasterSize; ++i )
@@ -636,6 +636,20 @@ char * QgsRasterBlock::bits( int row, int column )
return bits(( size_t )row*mWidth + column );
}

char * QgsRasterBlock::bits()
{
if ( mData )
{
return ( char* )mData;
}
if ( mImage && mImage->bits() )
{
return ( char* )( mImage->bits() );
}

return 0;
}

bool QgsRasterBlock::convert( QGis::DataType destDataType )
{
if ( isEmpty() ) return false;
@@ -714,22 +728,6 @@ bool QgsRasterBlock::setImage( const QImage * image )
return true;
}

// To give to an image preallocated memory is the only way to avoid memcpy
// when we want to keep data but delete QImage
QImage * QgsRasterBlock::createImage( int width, int height, QImage::Format format )
{
// Qt has its own internal function depthForFormat(), unfortunately it is not public

QImage img( 1, 1, format );

// We ignore QImage::Format_Mono and QImage::Format_MonoLSB ( depth 1)
int size = width * height * img.bytesPerLine();
uchar * data = ( uchar * ) malloc( size );
return new QImage( data, width, height, format );
}



QString QgsRasterBlock::printValue( double value )
{
/*
@@ -122,9 +122,8 @@ class CORE_EXPORT QgsRasterBlock
}

// Data type in bytes
int dataTypeSize( int bandNo ) const
int dataTypeSize( ) const
{
Q_UNUSED( bandNo );
return typeSize( mDataType );
}

@@ -150,31 +149,26 @@ class CORE_EXPORT QgsRasterBlock
* @return true if the block may contain no data */
bool hasNoData() const;

/** Return no data value.
/** Return no data value. If the block does not have a no data value the
* returned value is undefined.
* @return No data value */
double noDataValue() const { return mNoDataValue; }

/** Set no data value.
* @param noDataValue the value to be considered no data
*/
//void setNoDataValue( double noDataValue ) { mNoDataValue = noDataValue; }

/** Test if value is nodata comparing to noDataValue
* @param value tested value
* @param noDataValue no data value
* @return true if value is nodata */
static bool isNoDataValue( double value, double noDataValue );

// get byte array representing no data value
/** Get byte array representing a value.
* @param theDataType data type
* @param theValue value
* @return byte array representing the value */
static QByteArray valueBytes( QGis::DataType theDataType, double theValue );

/** \brief Read a single value
/** \brief Read a single value if type of block is numeric. If type is color,
* returned value is undefined.
* @param row row index
* @param column column index
* @return value */
double value( int row, int column ) const;

/** \brief Read a single value
/** \brief Read a single value if type of block is numeric. If type is color,
* returned value is undefined.
* @param index data matrix index
* @return value */
double value( size_t index ) const;
@@ -221,6 +215,12 @@ class CORE_EXPORT QgsRasterBlock
* @return true on success */
bool setColor( int row, int column, QRgb color );

/** \brief Set color on index (indexed line by line)
* @param index data matrix index
* @param color the color to be set, QRgb value
* @return true on success */
bool setColor( size_t index, QRgb color );

/** \brief Set no data on pixel
* @param row row index
* @param column column index
@@ -240,12 +240,6 @@ class CORE_EXPORT QgsRasterBlock
* @return true on success */
bool setIsNoDataExcept( const QRect & theExceptRect );

/** \brief Set color on index (indexed line by line)
* @param index data matrix index
* @param color the color to be set, QRgb value
* @return true on success */
bool setColor( size_t index, QRgb color );

/** \brief Get pointer to data
* @param row row index
* @param column column index
@@ -255,10 +249,13 @@ class CORE_EXPORT QgsRasterBlock

/** \brief Get pointer to data
* @param index data matrix index
* @return pointer to data
*/
* @return pointer to data */
char * bits( size_t index );

/** \brief Get pointer to data
* @return pointer to data */
char * bits();

/** \brief Print double value with all necessary significant digits.
* It is ensured that conversion back to double gives the same number.
* @param value the value to be printed
@@ -267,32 +264,17 @@ class CORE_EXPORT QgsRasterBlock

/** \brief Convert data to different type.
* @param destDataType dest data type
* @return true on success
*/
* @return true on success */
bool convert( QGis::DataType destDataType );

/** \brief Get image if type is color.
* @return image */
QImage image() const;
bool setImage( const QImage * image );

/** Create a new image with extraneous data, such data may be used
* after the image is destroyed. The memory is not initialized.
*/
// TODO: remove, no more necessary with QgsRasterBlock
QImage * createImage( int width, int height, QImage::Format format );

// TODO: remove this direct access to data, it was used in transition period
void * data() { if ( mData ) return mData; return mImage->bits(); }


// TODO: move to private, currently used by file writer
/** \brief Convert block of data from one type to another. Original block memory
* is not release.
* @param srcData source data
* @param srcDataType source data type
* @param destDataType dest data type
* @param size block size (width * height)
* @return block of data in destDataType */
static void * convert( void *srcData, QGis::DataType srcDataType, QGis::DataType destDataType, size_t size );
/** \brief set image.
* @param image image
* @return true on success */
bool setImage( const QImage * image );

inline static double readValue( void *data, QGis::DataType type, size_t index );

@@ -321,13 +303,30 @@ class CORE_EXPORT QgsRasterBlock
static QImage::Format imageFormat( QGis::DataType theDataType );
static QGis::DataType dataType( QImage::Format theFormat );

/** Test if value is nodata comparing to noDataValue
* @param value tested value
* @param noDataValue no data value
* @return true if value is nodata */
static bool isNoDataValue( double value, double noDataValue );

/** Test if value is nodata for specific band
* @param value tested value
* @return true if value is nodata */
bool isNoDataValue( double value ) const;

/** Allocate no data bitmap
* @return true on success */
bool createNoDataBitmap();

/** \brief Convert block of data from one type to another. Original block memory
* is not release.
* @param srcData source data
* @param srcDataType source data type
* @param destDataType dest data type
* @param size block size (width * height)
* @return block of data in destDataType */
static void * convert( void *srcData, QGis::DataType srcDataType, QGis::DataType destDataType, size_t size );

// Valid
bool mValid;

@@ -363,6 +362,7 @@ class CORE_EXPORT QgsRasterBlock

// number of bytes in mNoDataBitmap row
int mNoDataBitmapWidth;

// total size in bytes of mNoDataBitmap
size_t mNoDataBitmapSize;

@@ -372,19 +372,11 @@ class CORE_EXPORT QgsRasterBlock

inline double QgsRasterBlock::readValue( void *data, QGis::DataType type, size_t index )
{
#if 0
if ( !mInput )
{
return 0;
}

if ( !data )
{
return mInput->noDataValue();
return std::numeric_limits<double>::quiet_NaN();
}
#endif

// TODO: define QGIS types to avoid cpl_port.h
switch ( type )
{
case QGis::Byte:
@@ -409,12 +401,10 @@ inline double QgsRasterBlock::readValue( void *data, QGis::DataType type, size_t
return ( double )(( double * )data )[index];
break;
default:
//QgsMessageLog::logMessage( tr( "GDAL data type %1 is not supported" ).arg( type ), tr( "Raster" ) );
QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
break;
}

// TODO: noDataValue is per band
//return mInput->noDataValue();
return std::numeric_limits<double>::quiet_NaN();
}

@@ -446,31 +436,19 @@ inline void QgsRasterBlock::writeValue( void *data, QGis::DataType type, size_t
(( double * )data )[index] = value;
break;
default:
//QgsMessageLog::logMessage( tr( "GDAL data type %1 is not supported" ).arg( type ), tr( "Raster" ) );
QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
break;
}
}

inline double QgsRasterBlock::value( size_t index ) const
{
/*if ( index >= ( size_t )mWidth*mHeight )
{
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
return mNoDataValue;
}*/
return readValue( mData, mDataType, index );
}

inline bool QgsRasterBlock::isNoDataValue( double value ) const
{
// More precise would be qIsNaN(value) && qIsNaN(noDataValue(bandNo)), but probably
// not important and slower
if ( qIsNaN( value ) ||
qgsDoubleNear( value, mNoDataValue ) )
{
return true;
}
return false;
return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
}

#endif
@@ -178,7 +178,7 @@ QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle cons
tmpBlock = new QgsRasterBlock( dataType( theBandNo ), tmpWidth, tmpHeight );
}

readBlock( theBandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->data() );
readBlock( theBandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits() );

int pixelSize = dataTypeSize( theBandNo );

@@ -228,7 +228,7 @@ QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle cons
}
else
{
readBlock( theBandNo, theExtent, theWidth, theHeight, block->data() );
readBlock( theBandNo, theExtent, theWidth, theHeight, block->bits() );
}

// apply user no data values
@@ -385,7 +385,7 @@ QgsRasterBlock* QgsGdalProvider::block( int theBandNo, const QgsRectangle &theEx
QRect subRect = QgsRasterBlock::subRect( theExtent, theWidth, theHeight, mExtent );
block->setIsNoDataExcept( subRect );
}
readBlock( theBandNo, theExtent, theWidth, theHeight, block->data() );
readBlock( theBandNo, theExtent, theWidth, theHeight, block->bits() );
block->applyNoDataValues( userNoDataValue( theBandNo ) );
return block;
}

0 comments on commit 1f65f71

Please sign in to comment.
You can’t perform that action at this time.