21 #include "cpl_string.h"
25 #include "qgsconfig.h"
39 : mInputFile( inputFile )
40 , mOutputFile( outputFile )
41 , mOutputFormat( outputFormat )
54 if ( ! source.isEmpty() )
58 QgsDebugMsg( QObject::tr(
"Running OpenCL program: %1" ).arg( openClProgramBaseName( ) ) );
59 return processRasterGPU( source, feedback );
61 catch ( cl::Error &e )
63 const QString err = QObject::tr(
"Error running OpenCL program: %1 - %2" ).arg( e.what( ),
QgsOpenClUtils::errorText( e.err( ) ) );
70 const QString err = QObject::tr(
"Error loading OpenCL program sources" );
78 return processRasterCPU( feedback );
84 return processRasterCPU( feedback );
93 nCellsX = GDALGetRasterXSize( inputDataset.get() );
94 nCellsY = GDALGetRasterYSize( inputDataset.get() );
97 if ( GDALGetRasterCount( inputDataset.get() ) < 1 )
105 GDALDriverH QgsNineCellFilter::openOutputDriver()
108 GDALDriverH outputDriver = GDALGetDriverByName(
mOutputFormat.toLocal8Bit().data() );
131 const int xSize = GDALGetRasterXSize( inputDataset );
132 const int ySize = GDALGetRasterYSize( inputDataset );
135 char **papszOptions =
nullptr;
137 if ( !outputDataset )
139 return outputDataset;
143 double geotransform[6];
144 if ( GDALGetGeoTransform( inputDataset, geotransform ) != CE_None )
148 GDALSetGeoTransform( outputDataset.get(), geotransform );
162 const char *projection = GDALGetProjectionRef( inputDataset );
163 GDALSetProjection( outputDataset.get(), projection );
165 return outputDataset;
171 int QgsNineCellFilter::processRasterGPU(
const QString &source,
QgsFeedback *feedback )
185 GDALDriverH outputDriver = openOutputDriver();
192 if ( !outputDataset )
198 GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset.get(), 1 );
205 GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );
206 if ( !outputRasterBand )
211 GDALSetRasterNoDataValue( outputRasterBand, -9999 );
228 std::vector<float> rasterParams;
238 addExtraRasterParams( rasterParams );
240 const std::size_t bufferSize(
sizeof(
float ) * ( xSize + 2 ) );
241 const std::size_t inputSize(
sizeof(
float ) * ( xSize ) );
243 cl::Buffer rasterParamsBuffer( queue, rasterParams.begin(), rasterParams.end(),
true,
false,
nullptr );
244 cl::Buffer scanLine1Buffer( ctx, CL_MEM_READ_ONLY, bufferSize,
nullptr,
nullptr );
245 cl::Buffer scanLine2Buffer( ctx, CL_MEM_READ_ONLY, bufferSize,
nullptr,
nullptr );
246 cl::Buffer scanLine3Buffer( ctx, CL_MEM_READ_ONLY, bufferSize,
nullptr,
nullptr );
247 cl::Buffer *scanLineBuffer[3] = {&scanLine1Buffer, &scanLine2Buffer, &scanLine3Buffer};
248 cl::Buffer resultLineBuffer( ctx, CL_MEM_WRITE_ONLY, inputSize,
nullptr,
nullptr );
254 auto kernel = cl::KernelFunctor <
260 > ( program,
"processNineCellWindow" );
263 std::vector<int> rowIndex = {0, 1, 2};
266 for (
int i = 0; i < ySize; ++i )
275 feedback->
setProgress( 100.0 *
static_cast< double >( i ) / ySize );
282 for (
int a = 0; a < xSize + 2 ; ++a )
286 queue.enqueueWriteBuffer( scanLine1Buffer, CL_TRUE, 0, bufferSize, scanLine.get() );
289 if ( GDALRasterIO( rasterBand, GF_Read, 0, i, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
291 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
293 queue.enqueueWriteBuffer( scanLine2Buffer, CL_TRUE, 0, bufferSize, scanLine.get() );
296 if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
298 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
300 queue.enqueueWriteBuffer( scanLine3Buffer, CL_TRUE, 0, bufferSize, scanLine.get() );
306 if ( i == ySize - 1 )
308 for (
int a = 0; a < xSize + 2; ++a )
312 queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine.get() );
317 if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
319 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
321 queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine.get() );
325 kernel( cl::EnqueueArgs(
329 *scanLineBuffer[rowIndex[0]],
330 *scanLineBuffer[rowIndex[1]],
331 *scanLineBuffer[rowIndex[2]],
336 queue.enqueueReadBuffer( resultLineBuffer, CL_TRUE, 0, inputSize, resultLine.get() );
338 if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, xSize, 1, resultLine.get(), xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
340 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
342 std::rotate( rowIndex.begin(), rowIndex.begin() + 1, rowIndex.end() );
357 int QgsNineCellFilter::processRasterCPU(
QgsFeedback *feedback )
371 GDALDriverH outputDriver = openOutputDriver();
378 if ( !outputDataset )
384 GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset.get(), 1 );
391 GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );
392 if ( !outputRasterBand )
397 GDALSetRasterNoDataValue( outputRasterBand, -9999 );
406 const std::size_t bufferSize(
sizeof(
float ) * ( xSize + 2 ) );
407 float *scanLine1 = (
float * ) CPLMalloc( bufferSize );
408 float *scanLine2 = (
float * ) CPLMalloc( bufferSize );
409 float *scanLine3 = (
float * ) CPLMalloc( bufferSize );
411 float *resultLine = (
float * ) CPLMalloc(
sizeof(
float ) * xSize );
414 for (
int yIndex = 0; yIndex < ySize; ++yIndex )
423 feedback->
setProgress( 100.0 *
static_cast< double >( yIndex ) / ySize );
429 for (
int a = 0; a < xSize + 2 ; ++a )
434 if ( GDALRasterIO( rasterBand, GF_Read, 0, 0, xSize, 1, &scanLine2[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
436 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
442 CPLFree( scanLine1 );
443 scanLine1 = scanLine2;
444 scanLine2 = scanLine3;
445 scanLine3 = (
float * ) CPLMalloc( bufferSize );
449 if ( yIndex == ySize - 1 )
451 for (
int a = 0; a < xSize + 2; ++a )
458 if ( GDALRasterIO( rasterBand, GF_Read, 0, yIndex + 1, xSize, 1, &scanLine3[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
460 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
471 for (
int xIndex = 0; xIndex < xSize ; ++xIndex )
474 resultLine[ xIndex ] =
processNineCellWindow( &scanLine1[ xIndex ], &scanLine1[ xIndex + 1 ], &scanLine1[ xIndex + 2 ],
475 &scanLine2[ xIndex ], &scanLine2[ xIndex + 1 ], &scanLine2[ xIndex + 2 ],
476 &scanLine3[ xIndex ], &scanLine3[ xIndex + 1 ], &scanLine3[ xIndex + 2 ] );
480 if ( GDALRasterIO( outputRasterBand, GF_Write, 0, yIndex, xSize, 1, resultLine, xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
482 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
486 CPLFree( resultLine );
487 CPLFree( scanLine1 );
488 CPLFree( scanLine2 );
489 CPLFree( scanLine3 );