Add constBits methods to QgsRasterBlock

These can avoid an unwanted QImage detach when we are just
reading block data and don't need to modify it
This commit is contained in:
Nyall Dawson 2024-05-20 10:54:46 +10:00
parent fb1eabbf0b
commit 80b61d3d52
7 changed files with 83 additions and 9 deletions

View File

@ -352,6 +352,8 @@ overwrite data somewhere in the middle of the internal buffer.
static QString printValue( double value );
%Docstring
Print double value with all necessary significant digits.

View File

@ -352,6 +352,8 @@ overwrite data somewhere in the middle of the internal buffer.
static QString printValue( double value );
%Docstring
Print double value with all necessary significant digits.

View File

@ -506,9 +506,35 @@ char *QgsRasterBlock::bits( qgssize index )
{
return reinterpret_cast< char * >( mData ) + index * mTypeSize;
}
if ( mImage && mImage->bits() )
if ( mImage )
{
return reinterpret_cast< char * >( mImage->bits() + index * 4 );
if ( uchar *data = mImage->bits() )
{
return reinterpret_cast< char * >( data + index * 4 );
}
}
return nullptr;
}
const char *QgsRasterBlock::constBits( qgssize index ) const
{
// Not testing type to avoid too much overhead because this method is called per pixel
if ( index >= static_cast< qgssize >( mWidth )*mHeight )
{
QgsDebugMsgLevel( QStringLiteral( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ), 4 );
return nullptr;
}
if ( mData )
{
return reinterpret_cast< const char * >( mData ) + index * mTypeSize;
}
if ( mImage )
{
if ( const uchar *data = mImage->constBits() )
{
return reinterpret_cast< const char * >( data + index * 4 );
}
}
return nullptr;
@ -525,9 +551,29 @@ char *QgsRasterBlock::bits()
{
return reinterpret_cast< char * >( mData );
}
if ( mImage && mImage->bits() )
if ( mImage )
{
return reinterpret_cast< char * >( mImage->bits() );
if ( uchar *data = mImage->bits() )
{
return reinterpret_cast< char * >( data );
}
}
return nullptr;
}
const char *QgsRasterBlock::constBits() const
{
if ( mData )
{
return reinterpret_cast< const char * >( mData );
}
if ( mImage )
{
if ( const uchar *data = mImage->constBits() )
{
return reinterpret_cast< const char * >( data );
}
}
return nullptr;

View File

@ -552,15 +552,39 @@ class CORE_EXPORT QgsRasterBlock
* Returns a pointer to block data.
* \param index data matrix index (long type in Python)
* \note not available in Python bindings
*
* \see constBits()
*/
char *bits( qgssize index ) SIP_SKIP;
/**
* Returns a pointer to block data.
* \note not available in Python bindings
*
* \see constBits()
*/
char *bits() SIP_SKIP;
/**
* Returns a const pointer to block data.
*
* \param index data matrix index (long type in Python)
* \note not available in Python bindings
*
* \see bits()
* \since QGIS 3.38
*/
const char *constBits( qgssize index ) const SIP_SKIP;
/**
* Returns a const pointer to block data.
* \note not available in Python bindings
*
* \see bits()
* \since QGIS 3.38
*/
const char *constBits() const SIP_SKIP;
/**
* \brief Print double value with all necessary significant digits.
* It is ensured that conversion back to double gives the same number.

View File

@ -197,7 +197,7 @@ QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &b
const qgssize tmpIndex = static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
const qgssize index = row * static_cast< qgssize >( width ) + col;
char *tmpBits = tmpBlock->bits( tmpIndex );
const char *tmpBits = tmpBlock->constBits( tmpIndex );
char *bits = block->bits( index );
if ( !tmpBits )
{

View File

@ -529,7 +529,7 @@ Qgis::RasterFileWriterResult QgsRasterFileWriter::writeDataRaster( const QgsRast
if ( destBlockList[ i - 1 ]->isEmpty() )
continue;
if ( !partDestProvider->write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, 0, 0 ) )
if ( !partDestProvider->write( destBlockList[i - 1]->constBits( 0 ), i, iterCols, iterRows, 0, 0 ) )
{
return Qgis::RasterFileWriterResult::WriteError;
}
@ -545,7 +545,7 @@ Qgis::RasterFileWriterResult QgsRasterFileWriter::writeDataRaster( const QgsRast
if ( destBlockList[ i - 1 ]->isEmpty() )
continue;
if ( !destProvider->write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, iterLeft, iterTop ) )
if ( !destProvider->write( destBlockList[i - 1]->constBits( 0 ), i, iterCols, iterRows, iterLeft, iterTop ) )
{
return Qgis::RasterFileWriterResult::WriteError;
}

View File

@ -901,8 +901,8 @@ QgsRasterBlock *QgsRasterProjector::block( int bandNo, QgsRectangle const &exte
}
const qgssize destIndex = static_cast< qgssize >( i ) * width + j;
char *srcBits = inputBlock->bits( srcIndex );
char *destBits = outputBlock->bits( destIndex );
const char *srcBits = inputBlock->constBits( srcIndex );
char *destBits = output->bits( destIndex );
if ( !srcBits )
{
// QgsDebugError( QStringLiteral( "Cannot get input block data: row = %1 col = %2" ).arg( i ).arg( j ) );