@@ -41,6 +41,8 @@ GDALRasterPipelineStepAlgorithm::GDALRasterPipelineStepAlgorithm(
41
41
{
42
42
if (m_standaloneStep)
43
43
{
44
+ m_supportsStreamedOutput = true ;
45
+
44
46
AddInputArgs (false , false );
45
47
AddProgressArg ();
46
48
AddOutputArgs (false );
@@ -76,7 +78,8 @@ void GDALRasterPipelineStepAlgorithm::AddInputArgs(
76
78
77
79
void GDALRasterPipelineStepAlgorithm::AddOutputArgs (bool hiddenForCLI)
78
80
{
79
- AddOutputFormatArg (&m_format)
81
+ AddOutputFormatArg (&m_format, /* bStreamAllowed = */ true ,
82
+ /* bGDALGAllowed = */ true )
80
83
.AddMetadataItem (GAAMDI_REQUIRED_CAPABILITIES,
81
84
{GDAL_DCAP_RASTER, GDAL_DCAP_CREATECOPY})
82
85
.SetHiddenForCLI (hiddenForCLI);
@@ -119,20 +122,38 @@ bool GDALRasterPipelineStepAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
119
122
}
120
123
}
121
124
125
+ if (m_executionForStreamOutput && !EQUAL (m_format.c_str (), " stream" ))
126
+ {
127
+ // For security reasons, to avoid that reading a .gdalg.json file
128
+ // writes a file on the file system.
129
+ ReportError (CE_Failure, CPLE_NotSupported,
130
+ " gdal raster pipeline in streamed execution should use "
131
+ " --format stream" );
132
+ return false ;
133
+ }
134
+
122
135
bool ret = false ;
123
136
if (readAlg.Run ())
124
137
{
125
138
m_inputDataset.Set (readAlg.m_outputDataset .GetDatasetRef ());
126
139
m_outputDataset.Set (nullptr );
127
140
if (RunStep (nullptr , nullptr ))
128
141
{
129
- writeAlg.m_inputDataset .Set (m_outputDataset.GetDatasetRef ());
130
- if (writeAlg.Run (pfnProgress, pProgressData))
142
+ if (m_format == " stream" )
131
143
{
132
- m_outputDataset.Set (
133
- writeAlg.m_outputDataset .GetDatasetRef ());
134
144
ret = true ;
135
145
}
146
+ else
147
+ {
148
+ writeAlg.m_inputDataset .Set (
149
+ m_outputDataset.GetDatasetRef ());
150
+ if (writeAlg.Run (pfnProgress, pProgressData))
151
+ {
152
+ m_outputDataset.Set (
153
+ writeAlg.m_outputDataset .GetDatasetRef ());
154
+ ret = true ;
155
+ }
156
+ }
136
157
}
137
158
}
138
159
@@ -144,6 +165,44 @@ bool GDALRasterPipelineStepAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
144
165
}
145
166
}
146
167
168
+ /* ***********************************************************************/
169
+ /* ProcessGDALGOutput() */
170
+ /* ***********************************************************************/
171
+
172
+ GDALAlgorithm::ProcessGDALGOutputRet
173
+ GDALRasterPipelineStepAlgorithm::ProcessGDALGOutput ()
174
+ {
175
+ if (m_standaloneStep)
176
+ {
177
+ return GDALAlgorithm::ProcessGDALGOutput ();
178
+ }
179
+ else
180
+ {
181
+ // GDALAbstractPipelineAlgorithm<StepAlgorithm>::RunStep() might
182
+ // actually detect a GDALG output request and process it.
183
+ return GDALAlgorithm::ProcessGDALGOutputRet::NOT_GDALG;
184
+ }
185
+ }
186
+
187
+ /* ***********************************************************************/
188
+ /* GDALRasterPipelineStepAlgorithm::CheckSafeForStreamOutput() */
189
+ /* ***********************************************************************/
190
+
191
+ bool GDALRasterPipelineStepAlgorithm::CheckSafeForStreamOutput ()
192
+ {
193
+ if (m_standaloneStep)
194
+ {
195
+ return GDALAlgorithm::CheckSafeForStreamOutput ();
196
+ }
197
+ else
198
+ {
199
+ // The check is actually done in
200
+ // GDALAbstractPipelineAlgorithm<StepAlgorithm>::RunStep()
201
+ // so return true for now.
202
+ return true ;
203
+ }
204
+ }
205
+
147
206
/* ***********************************************************************/
148
207
/* GDALRasterPipelineAlgorithm::GDALRasterPipelineAlgorithm() */
149
208
/* ***********************************************************************/
@@ -154,6 +213,8 @@ GDALRasterPipelineAlgorithm::GDALRasterPipelineAlgorithm(
154
213
NAME, DESCRIPTION, HELP_URL,
155
214
/* standaloneStep=*/ false )
156
215
{
216
+ m_supportsStreamedOutput = true ;
217
+
157
218
AddInputArgs (openForMixedRasterVector, /* hiddenForCLI = */ true );
158
219
AddProgressArg ();
159
220
AddArg (" pipeline" , 0 , _ (" Pipeline string" ), &m_pipeline)
@@ -285,6 +346,18 @@ bool GDALRasterPipelineAlgorithm::ParseCommandLineArguments(
285
346
if (!steps.back ().alg )
286
347
steps.pop_back ();
287
348
349
+ // Automatically add a final write step if none in m_executionForStreamOutput
350
+ // mode
351
+ if (m_executionForStreamOutput && !steps.empty () &&
352
+ steps.back ().alg ->GetName () != GDALRasterWriteAlgorithm::NAME)
353
+ {
354
+ steps.resize (steps.size () + 1 );
355
+ steps.back ().alg = GetStepAlg (GDALRasterWriteAlgorithm::NAME);
356
+ steps.back ().args .push_back (" --output-format" );
357
+ steps.back ().args .push_back (" stream" );
358
+ steps.back ().args .push_back (" streamed_dataset" );
359
+ }
360
+
288
361
if (steps.size () < 2 )
289
362
{
290
363
ReportError (CE_Failure, CPLE_AppDefined,
@@ -325,6 +398,12 @@ bool GDALRasterPipelineAlgorithm::ParseCommandLineArguments(
325
398
}
326
399
}
327
400
401
+ for (auto &step : steps)
402
+ {
403
+ step.alg ->SetReferencePathForRelativePaths (
404
+ GetReferencePathForRelativePaths ());
405
+ }
406
+
328
407
if (!m_pipeline.empty ())
329
408
{
330
409
// Propagate input parameters set at the pipeline level to the
0 commit comments