QgsRasterBlock* QgsSingleBandColorDataRenderer::block( int bandNo, QgsRectangle const & extent, int width, int height ) { Q_UNUSED( bandNo ); QgsRasterBlock *outputBlock = new QgsRasterBlock(); if ( !mInput ) { return outputBlock; } QgsRasterBlock *inputBlock = mInput->block( mBand, extent, width, height ); if ( !inputBlock || inputBlock->isEmpty() ) { QgsDebugMsg( "No raster data!" ); delete inputBlock; return outputBlock; } bool hasTransparency = usesTransparency(); if ( !hasTransparency ) { // Nothing to do, just retype if necessary inputBlock->convert( QgsRasterBlock::ARGB32_Premultiplied ); delete outputBlock; return inputBlock; } if ( !outputBlock->reset( QgsRasterBlock::ARGB32_Premultiplied, width, height ) ) { delete inputBlock; return outputBlock; } for ( size_t i = 0; i < ( size_t )width*height; i++ ) { QRgb pixelColor; double alpha = 255.0; QRgb c = inputBlock->color( i ); alpha = qAlpha( c ); pixelColor = qRgba( mOpacity * qRed( c ), mOpacity * qGreen( c ), mOpacity * qBlue( c ), mOpacity * alpha ); outputBlock->setColor( i, pixelColor ); } delete inputBlock; return outputBlock; }
QgsRasterBlock * QgsHueSaturationFilter::block( int bandNo, QgsRectangle const & extent, int width, int height, QgsRasterBlockFeedback* feedback ) { Q_UNUSED( bandNo ); QgsDebugMsgLevel( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ), 4 ); QgsRasterBlock *outputBlock = new QgsRasterBlock(); if ( !mInput ) { return outputBlock; } // At this moment we know that we read rendered image int bandNumber = 1; QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, width, height, feedback ); if ( !inputBlock || inputBlock->isEmpty() ) { QgsDebugMsg( "No raster data!" ); delete inputBlock; return outputBlock; } if ( mSaturation == 0 && mGrayscaleMode == GrayscaleOff && !mColorizeOn ) { QgsDebugMsgLevel( "No hue/saturation change.", 4 ); delete outputBlock; return inputBlock; } if ( !outputBlock->reset( Qgis::ARGB32_Premultiplied, width, height ) ) { delete inputBlock; return outputBlock; } // adjust image QRgb myNoDataColor = qRgba( 0, 0, 0, 0 ); QRgb myRgb; QColor myColor; int h, s, l; int r, g, b, alpha; double alphaFactor = 1.0; for ( qgssize i = 0; i < ( qgssize )width*height; i++ ) { if ( inputBlock->color( i ) == myNoDataColor ) { outputBlock->setColor( i, myNoDataColor ); continue; } myRgb = inputBlock->color( i ); myColor = QColor( myRgb ); // Alpha must be taken from QRgb, since conversion from QRgb->QColor loses alpha alpha = qAlpha( myRgb ); if ( alpha == 0 ) { // totally transparent, no changes required outputBlock->setColor( i, myRgb ); continue; } // Get rgb for color myColor.getRgb( &r, &g, &b ); if ( alpha != 255 ) { // Semi-transparent pixel. We need to adjust the colors since we are using Qgis::ARGB32_Premultiplied // and color values have been premultiplied by alpha alphaFactor = alpha / 255.; r /= alphaFactor; g /= alphaFactor; b /= alphaFactor; myColor = QColor::fromRgb( r, g, b ); } myColor.getHsl( &h, &s, &l ); // Changing saturation? if (( mGrayscaleMode != GrayscaleOff ) || ( mSaturationScale != 1 ) ) { processSaturation( r, g, b, h, s, l ); } // Colorizing? if ( mColorizeOn ) { processColorization( r, g, b, h, s, l ); } // Convert back to rgb if ( alpha != 255 ) { // Transparent pixel, need to premultiply color components r *= alphaFactor; g *= alphaFactor; b *= alphaFactor; } outputBlock->setColor( i, qRgba( r, g, b, alpha ) ); } delete inputBlock; return outputBlock; }
QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRasterIterator* iter, int nCols, int nRows, const QgsRectangle& outputExtent, const QgsCoordinateReferenceSystem& crs, QProgressDialog* progressDialog ) { QgsDebugMsg( "Entered" ); if ( !iter ) { return SourceProviderError; } const QgsRasterInterface* iface = iter->input(); QGis::DataType inputDataType = iface->dataType( 1 ); if ( !iface || ( inputDataType != QGis::ARGB32 && inputDataType != QGis::ARGB32_Premultiplied ) ) { return SourceProviderError; } iter->setMaximumTileWidth( mMaxTileWidth ); iter->setMaximumTileHeight( mMaxTileHeight ); void* redData = qgsMalloc( mMaxTileWidth * mMaxTileHeight ); void* greenData = qgsMalloc( mMaxTileWidth * mMaxTileHeight ); void* blueData = qgsMalloc( mMaxTileWidth * mMaxTileHeight ); void* alphaData = qgsMalloc( mMaxTileWidth * mMaxTileHeight ); QgsRectangle mapRect; int iterLeft = 0, iterTop = 0, iterCols = 0, iterRows = 0; int fileIndex = 0; //create destProvider for whole dataset here QgsRasterDataProvider* destProvider = 0; double pixelSize; double geoTransform[6]; globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize ); destProvider = initOutput( nCols, nRows, crs, geoTransform, 4, QGis::Byte ); iter->startRasterRead( 1, nCols, nRows, outputExtent ); int nParts = 0; if ( progressDialog ) { int nPartsX = nCols / iter->maximumTileWidth() + 1; int nPartsY = nRows / iter->maximumTileHeight() + 1; nParts = nPartsX * nPartsY; progressDialog->setMaximum( nParts ); progressDialog->show(); progressDialog->setLabelText( QObject::tr( "Reading raster part %1 of %2" ).arg( fileIndex + 1 ).arg( nParts ) ); } QgsRasterBlock *inputBlock = 0; while ( iter->readNextRasterPart( 1, iterCols, iterRows, &inputBlock, iterLeft, iterTop ) ) { if ( !inputBlock ) { continue; } if ( progressDialog && fileIndex < ( nParts - 1 ) ) { progressDialog->setValue( fileIndex + 1 ); progressDialog->setLabelText( QObject::tr( "Reading raster part %1 of %2" ).arg( fileIndex + 2 ).arg( nParts ) ); QCoreApplication::processEvents( QEventLoop::AllEvents, 1000 ); if ( progressDialog->wasCanceled() ) { delete inputBlock; break; } } //fill into red/green/blue/alpha channels qgssize nPixels = ( qgssize )iterCols * iterRows; // TODO: should be char not int? we are then copying 1 byte int red = 0; int green = 0; int blue = 0; int alpha = 255; for ( qgssize i = 0; i < nPixels; ++i ) { QRgb c = inputBlock->color( i ); alpha = qAlpha( c ); red = qRed( c ); green = qGreen( c ); blue = qBlue( c ); if ( inputDataType == QGis::ARGB32_Premultiplied ) { double a = alpha / 255.; QgsDebugMsgLevel( QString( "red = %1 green = %2 blue = %3 alpha = %4 p = %5 a = %6" ).arg( red ).arg( green ).arg( blue ).arg( alpha ).arg(( int )c, 0, 16 ).arg( a ), 5 ); red /= a; green /= a; blue /= a; } memcpy(( char* )redData + i, &red, 1 ); memcpy(( char* )greenData + i, &green, 1 ); memcpy(( char* )blueData + i, &blue, 1 ); memcpy(( char* )alphaData + i, &alpha, 1 ); } delete inputBlock; //create output file if ( mTiledMode ) { //delete destProvider; QgsRasterDataProvider* partDestProvider = createPartProvider( outputExtent, nCols, iterCols, iterRows, iterLeft, iterTop, mOutputUrl, fileIndex, 4, QGis::Byte, crs ); if ( partDestProvider ) { //write data to output file partDestProvider->write( redData, 1, iterCols, iterRows, 0, 0 ); partDestProvider->write( greenData, 2, iterCols, iterRows, 0, 0 ); partDestProvider->write( blueData, 3, iterCols, iterRows, 0, 0 ); partDestProvider->write( alphaData, 4, iterCols, iterRows, 0, 0 ); addToVRT( partFileName( fileIndex ), 1, iterCols, iterRows, iterLeft, iterTop ); addToVRT( partFileName( fileIndex ), 2, iterCols, iterRows, iterLeft, iterTop ); addToVRT( partFileName( fileIndex ), 3, iterCols, iterRows, iterLeft, iterTop ); addToVRT( partFileName( fileIndex ), 4, iterCols, iterRows, iterLeft, iterTop ); delete partDestProvider; } } else if ( destProvider ) { destProvider->write( redData, 1, iterCols, iterRows, iterLeft, iterTop ); destProvider->write( greenData, 2, iterCols, iterRows, iterLeft, iterTop ); destProvider->write( blueData, 3, iterCols, iterRows, iterLeft, iterTop ); destProvider->write( alphaData, 4, iterCols, iterRows, iterLeft, iterTop ); } ++fileIndex; } if ( destProvider ) delete destProvider; qgsFree( redData ); qgsFree( greenData ); qgsFree( blueData ); qgsFree( alphaData ); if ( progressDialog ) { progressDialog->setValue( progressDialog->maximum() ); } if ( mTiledMode ) { QString vrtFilePath( mOutputUrl + "/" + vrtFileName() ); writeVRT( vrtFilePath ); if ( mBuildPyramidsFlag == QgsRaster::PyramidsFlagYes ) { buildPyramids( vrtFilePath ); } } else { if ( mBuildPyramidsFlag == QgsRaster::PyramidsFlagYes ) { buildPyramids( mOutputUrl ); } } return NoError; }
QgsRasterBlock * QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle const & extent, int width, int height ) { Q_UNUSED( bandNo ); QgsDebugMsg( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ) ); QgsRasterBlock *outputBlock = new QgsRasterBlock(); if ( !mInput ) { return outputBlock; } // At this moment we know that we read rendered image int bandNumber = 1; QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, width, height ); if ( !inputBlock || inputBlock->isEmpty() ) { QgsDebugMsg( "No raster data!" ); delete inputBlock; return outputBlock; } if ( mBrightness == 0 && mContrast == 0 ) { QgsDebugMsg( "No brightness changes." ); delete outputBlock; return inputBlock; } if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) ) { delete inputBlock; return outputBlock; } // adjust image QRgb myNoDataColor = qRgba( 0, 0, 0, 0 ); QRgb myColor; int r, g, b, alpha; double f = qPow(( mContrast + 100 ) / 100.0, 2 ); for ( qgssize i = 0; i < ( qgssize )width*height; i++ ) { if ( inputBlock->color( i ) == myNoDataColor ) { outputBlock->setColor( i, myNoDataColor ); continue; } myColor = inputBlock->color( i ); alpha = qAlpha( myColor ); r = adjustColorComponent( qRed( myColor ), alpha, mBrightness, f ); g = adjustColorComponent( qGreen( myColor ), alpha, mBrightness, f ); b = adjustColorComponent( qBlue( myColor ), alpha, mBrightness, f ); outputBlock->setColor( i, qRgba( r, g, b, alpha ) ); } delete inputBlock; return outputBlock; }