diff --git a/python/core/auto_generated/raster/qgsrasterblock.sip.in b/python/core/auto_generated/raster/qgsrasterblock.sip.in index 3331dbed13d..b81f4991730 100644 --- a/python/core/auto_generated/raster/qgsrasterblock.sip.in +++ b/python/core/auto_generated/raster/qgsrasterblock.sip.in @@ -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 diff --git a/src/core/raster/qgsmultibandcolorrenderer.cpp b/src/core/raster/qgsmultibandcolorrenderer.cpp index 3c511c5f47b..8ffae9f7c24 100644 --- a/src/core/raster/qgsmultibandcolorrenderer.cpp +++ b/src/core/raster/qgsmultibandcolorrenderer.cpp @@ -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; } diff --git a/src/core/raster/qgsrasterblock.h b/src/core/raster/qgsrasterblock.h index bb8e80cabd7..6b3fd8c2969 100644 --- a/src/core/raster/qgsrasterblock.h +++ b/src/core/raster/qgsrasterblock.h @@ -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