Skip to content
Permalink
Browse files

Speed up rendering of RGB images

In my simple test case this made map rendering of RGB satellite image tiles
go down by ~50% from ~40ms per tile to ~20ms per tile (in debug version, ahem)
  • Loading branch information
wonder-sk committed Jul 9, 2018
1 parent c4b9106 commit 0a35d4355246646923f8e74ac1072441a3df3f00
@@ -166,6 +166,7 @@ returned value is undefined.
:return: value *
%End


QRgb color( int row, int column ) const;
%Docstring
Read a single color
@@ -246,6 +247,7 @@ Set color on index (indexed line by line)
:return: true on success *
%End


bool setIsNoData( int row, int column );
%Docstring
Set no data on pixel
@@ -225,9 +225,22 @@ QgsRasterBlock *QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle cons
return outputBlock.release();
}

QRgb *outputBlockColorData = outputBlock->colorData();

// faster data access to data for the common case that input data are coming from RGB image with 8-bit bands
bool hasByteRgb = ( redBlock->dataType() == Qgis::Byte && greenBlock->dataType() == Qgis::Byte && blueBlock->dataType() == Qgis::Byte );
const quint8 *redData = nullptr, *greenData = nullptr, *blueData = nullptr;
if ( hasByteRgb )
{
redData = redBlock->byteData();
greenData = greenBlock->byteData();
blueData = blueBlock->byteData();
}

QRgb myDefaultColor = NODATA_COLOR;

for ( qgssize i = 0; i < ( qgssize )width * height; i++ )
qgssize count = ( qgssize )width * height;
for ( qgssize i = 0; i < count; i++ )
{
if ( fastDraw ) //fast rendering if no transparency, stretching, color inversion, etc.
{
@@ -239,10 +252,17 @@ QgsRasterBlock *QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle cons
}
else
{
int redVal = ( int )redBlock->value( i );
int greenVal = ( int )greenBlock->value( i );
int blueVal = ( int )blueBlock->value( i );
outputBlock->setColor( i, qRgba( redVal, greenVal, blueVal, 255 ) );
if ( hasByteRgb )
{
outputBlockColorData[i] = qRgb( redData[i], greenData[i], blueData[i] );
}
else
{
int redVal = ( int )redBlock->value( i );
int greenVal = ( int )greenBlock->value( i );
int blueVal = ( int )blueBlock->value( i );
outputBlockColorData[i] = qRgb( redVal, greenVal, blueVal );
}
}
continue;
}
@@ -196,6 +196,20 @@ class CORE_EXPORT QgsRasterBlock
* \returns value */
double value( qgssize index ) const;

/**
* Gives direct access to the raster block data.
* The data type of the block must be Qgis::Byte otherwise it returns null pointer.
* Useful for most efficient read access.
* \note not available in Python bindings
* \since QGIS 3.4
*/
const quint8 *byteData() const SIP_SKIP
{
if ( mDataType != Qgis::Byte )
return nullptr;
return static_cast< const quint8 * >( mData );
}

/**
* \brief Read a single color
* \param row row index
@@ -332,6 +346,20 @@ class CORE_EXPORT QgsRasterBlock
return true;
}

/**
* Gives direct read/write access to the raster RGB data.
* The data type of the block must be Qgis::ARGB32 or Qgis::ARGB32_Premultiplied otherwise it returns null pointer.
* Useful for most efficient read/write access to RGB blocks.
* \note not available in Python bindings
* \since QGIS 3.4
*/
QRgb *colorData() SIP_SKIP
{
if ( !mImage )
return nullptr;
return reinterpret_cast< QRgb * >( mImage->bits() );
}

/**
* \brief Set no data on pixel
* \param row row index

0 comments on commit 0a35d43

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