21 #include "cpl_string.h"
38 : mInputFile( inputFile )
39 , mOutputFile( outputFile )
40 , mOutputFormat( outputFormat )
53 if ( ! source.isEmpty() )
57 QgsDebugMsg( QObject::tr(
"Running OpenCL program: %1" ).arg( openClProgramBaseName( ) ) );
58 return processRasterGPU( source, feedback );
60 catch ( cl::Error &e )
62 QString err = QObject::tr(
"Error running OpenCL program: %1 - %2" ).arg( e.what( ),
QgsOpenClUtils::errorText( e.err( ) ) );
69 QString err = QObject::tr(
"Error loading OpenCL program sources" );
77 return processRasterCPU( feedback );
83 return processRasterCPU( feedback );
92 nCellsX = GDALGetRasterXSize( inputDataset.get() );
93 nCellsY = GDALGetRasterYSize( inputDataset.get() );
96 if ( GDALGetRasterCount( inputDataset.get() ) < 1 )
104 GDALDriverH QgsNineCellFilter::openOutputDriver()
107 GDALDriverH outputDriver = GDALGetDriverByName(
mOutputFormat.toLocal8Bit().data() );
130 int xSize = GDALGetRasterXSize( inputDataset );
131 int ySize = GDALGetRasterYSize( inputDataset );
134 char **papszOptions =
nullptr;
136 if ( !outputDataset )
138 return outputDataset;
142 double geotransform[6];
143 if ( GDALGetGeoTransform( inputDataset, geotransform ) != CE_None )
147 GDALSetGeoTransform( outputDataset.get(), geotransform );
161 const char *projection = GDALGetProjectionRef( inputDataset );
162 GDALSetProjection( outputDataset.get(), projection );
164 return outputDataset;
170 int QgsNineCellFilter::processRasterGPU(
const QString &source,
QgsFeedback *feedback )
184 GDALDriverH outputDriver = openOutputDriver();
191 if ( !outputDataset )
197 GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset.get(), 1 );
204 GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );
205 if ( !outputRasterBand )
210 GDALSetRasterNoDataValue( outputRasterBand, -9999 );
227 std::vector<float> rasterParams;
237 addExtraRasterParams( rasterParams );
239 std::size_t bufferSize(
sizeof(
float ) * ( xSize + 2 ) );
240 std::size_t inputSize(
sizeof(
float ) * ( xSize ) );
242 cl::Buffer rasterParamsBuffer( queue, rasterParams.begin(), rasterParams.end(),
true,
false,
nullptr );
243 cl::Buffer scanLine1Buffer( ctx, CL_MEM_READ_ONLY, bufferSize,
nullptr,
nullptr );
244 cl::Buffer scanLine2Buffer( ctx, CL_MEM_READ_ONLY, bufferSize,
nullptr,
nullptr );
245 cl::Buffer scanLine3Buffer( ctx, CL_MEM_READ_ONLY, bufferSize,
nullptr,
nullptr );
246 cl::Buffer *scanLineBuffer[3] = {&scanLine1Buffer, &scanLine2Buffer, &scanLine3Buffer};
247 cl::Buffer resultLineBuffer( ctx, CL_MEM_WRITE_ONLY, inputSize,
nullptr,
nullptr );
253 auto kernel = cl::KernelFunctor <
259 > ( program,
"processNineCellWindow" );
262 std::vector<int> rowIndex = {0, 1, 2};
265 for (
int i = 0; i < ySize; ++i )
274 feedback->
setProgress( 100.0 *
static_cast< double >( i ) / ySize );
281 for (
int a = 0; a < xSize + 2 ; ++a )
285 queue.enqueueWriteBuffer( scanLine1Buffer, CL_TRUE, 0, bufferSize, scanLine.get() );
288 if ( GDALRasterIO( rasterBand, GF_Read, 0, i, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
290 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
292 queue.enqueueWriteBuffer( scanLine2Buffer, CL_TRUE, 0, bufferSize, scanLine.get() );
295 if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
297 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
299 queue.enqueueWriteBuffer( scanLine3Buffer, CL_TRUE, 0, bufferSize, scanLine.get() );
305 if ( i == ySize - 1 )
307 for (
int a = 0; a < xSize + 2; ++a )
311 queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine.get() );
316 if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
318 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
320 queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine.get() );
324 kernel( cl::EnqueueArgs(
328 *scanLineBuffer[rowIndex[0]],
329 *scanLineBuffer[rowIndex[1]],
330 *scanLineBuffer[rowIndex[2]],
335 queue.enqueueReadBuffer( resultLineBuffer, CL_TRUE, 0, inputSize, resultLine.get() );
337 if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, xSize, 1, resultLine.get(), xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
339 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
341 std::rotate( rowIndex.begin(), rowIndex.begin() + 1, rowIndex.end() );
356 int QgsNineCellFilter::processRasterCPU(
QgsFeedback *feedback )
370 GDALDriverH outputDriver = openOutputDriver();
377 if ( !outputDataset )
383 GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset.get(), 1 );
390 GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );
391 if ( !outputRasterBand )
396 GDALSetRasterNoDataValue( outputRasterBand, -9999 );
405 std::size_t bufferSize(
sizeof(
float ) * ( xSize + 2 ) );
406 float *scanLine1 = (
float * ) CPLMalloc( bufferSize );
407 float *scanLine2 = (
float * ) CPLMalloc( bufferSize );
408 float *scanLine3 = (
float * ) CPLMalloc( bufferSize );
410 float *resultLine = (
float * ) CPLMalloc(
sizeof(
float ) * xSize );
413 for (
int yIndex = 0; yIndex < ySize; ++yIndex )
422 feedback->
setProgress( 100.0 *
static_cast< double >( yIndex ) / ySize );
428 for (
int a = 0; a < xSize + 2 ; ++a )
433 if ( GDALRasterIO( rasterBand, GF_Read, 0, 0, xSize, 1, &scanLine2[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
435 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
441 CPLFree( scanLine1 );
442 scanLine1 = scanLine2;
443 scanLine2 = scanLine3;
444 scanLine3 = (
float * ) CPLMalloc( bufferSize );
448 if ( yIndex == ySize - 1 )
450 for (
int a = 0; a < xSize + 2; ++a )
457 if ( GDALRasterIO( rasterBand, GF_Read, 0, yIndex + 1, xSize, 1, &scanLine3[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
459 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
470 for (
int xIndex = 0; xIndex < xSize ; ++xIndex )
473 resultLine[ xIndex ] =
processNineCellWindow( &scanLine1[ xIndex ], &scanLine1[ xIndex + 1 ], &scanLine1[ xIndex + 2 ],
474 &scanLine2[ xIndex ], &scanLine2[ xIndex + 1 ], &scanLine2[ xIndex + 2 ],
475 &scanLine3[ xIndex ], &scanLine3[ xIndex + 1 ], &scanLine3[ xIndex + 2 ] );
479 if ( GDALRasterIO( outputRasterBand, GF_Write, 0, yIndex, xSize, 1, resultLine, xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
481 QgsDebugMsg( QStringLiteral(
"Raster IO Error" ) );
485 CPLFree( resultLine );
486 CPLFree( scanLine1 );
487 CPLFree( scanLine2 );
488 CPLFree( scanLine3 );