Coverage Report

Created: 2026-04-01 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_raster_write.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  "write" step of "raster pipeline"
5
 * Author:   Even Rouault <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "gdalalg_raster_write.h"
14
15
#include "cpl_string.h"
16
#include "gdal_utils.h"
17
#include "gdal_priv.h"
18
19
//! @cond Doxygen_Suppress
20
21
/************************************************************************/
22
/*         GDALRasterWriteAlgorithm::GDALRasterWriteAlgorithm()         */
23
/************************************************************************/
24
25
GDALRasterWriteAlgorithm::GDALRasterWriteAlgorithm()
26
0
    : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
27
0
                                      /* standaloneStep =*/false)
28
0
{
29
0
    AddRasterOutputArgs(/* hiddenForCLI = */ false);
30
0
}
31
32
/************************************************************************/
33
/*                 GDALRasterWriteAlgorithm::RunStep()                  */
34
/************************************************************************/
35
36
bool GDALRasterWriteAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt)
37
0
{
38
0
    auto pfnProgress = ctxt.m_pfnProgress;
39
0
    auto pProgressData = ctxt.m_pProgressData;
40
0
    auto poSrcDS = m_inputDataset[0].GetDatasetRef();
41
0
    CPLAssert(poSrcDS);
42
0
    CPLAssert(!m_outputDataset.GetDatasetRef());
43
44
0
    if (m_format == "stream")
45
0
    {
46
0
        m_outputDataset.Set(poSrcDS);
47
0
        return true;
48
0
    }
49
50
0
    CPLStringList aosOptions;
51
0
    if (!m_overwrite)
52
0
    {
53
0
        aosOptions.AddString("--no-overwrite");
54
0
    }
55
0
    if (m_appendRaster)
56
0
    {
57
0
        CPLErrorStateBackuper oBackuper(CPLQuietErrorHandler);
58
0
        if (std::unique_ptr<GDALDataset>(GDALDataset::Open(
59
0
                m_outputDataset.GetName().c_str(), GDAL_OF_RASTER)))
60
0
        {
61
0
            aosOptions.AddString("-co");
62
0
            aosOptions.AddString("APPEND_SUBDATASET=YES");
63
0
        }
64
0
    }
65
0
    if (!m_format.empty())
66
0
    {
67
0
        aosOptions.AddString("-of");
68
0
        aosOptions.AddString(m_format.c_str());
69
0
    }
70
0
    for (const auto &co : m_creationOptions)
71
0
    {
72
0
        aosOptions.AddString("-co");
73
0
        aosOptions.AddString(co.c_str());
74
0
    }
75
76
0
    GDALTranslateOptions *psOptions =
77
0
        GDALTranslateOptionsNew(aosOptions.List(), nullptr);
78
0
    GDALTranslateOptionsSetProgress(psOptions, pfnProgress, pProgressData);
79
80
    // Backup error state since GDALTranslate() resets it multiple times
81
0
    const auto nLastErrorNum = CPLGetLastErrorNo();
82
0
    const auto nLastErrorType = CPLGetLastErrorType();
83
0
    const std::string osLastErrorMsg = CPLGetLastErrorMsg();
84
0
    const auto nLastErrorCounter = CPLGetErrorCounter();
85
86
0
    GDALDatasetH hSrcDS = GDALDataset::ToHandle(poSrcDS);
87
0
    auto poRetDS = GDALDataset::FromHandle(GDALTranslate(
88
0
        m_outputDataset.GetName().c_str(), hSrcDS, psOptions, nullptr));
89
0
    GDALTranslateOptionsFree(psOptions);
90
91
0
    if (nLastErrorCounter > 0 && CPLGetErrorCounter() == 0)
92
0
    {
93
0
        CPLErrorSetState(nLastErrorType, nLastErrorNum, osLastErrorMsg.c_str(),
94
0
                         &nLastErrorCounter);
95
0
    }
96
97
0
    if (!poRetDS)
98
0
        return false;
99
100
0
    m_outputDataset.Set(std::unique_ptr<GDALDataset>(poRetDS));
101
102
0
    return true;
103
0
}
104
105
//! @endcond