Coverage Report

Created: 2026-02-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_raster_select.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  "select" step of "raster pipeline"
5
 * Author:   Even Rouault <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "gdalalg_raster_select.h"
14
15
#include "gdal_priv.h"
16
#include "gdal_utils.h"
17
18
//! @cond Doxygen_Suppress
19
20
#ifndef _
21
0
#define _(x) (x)
22
#endif
23
24
/************************************************************************/
25
/*        GDALRasterSelectAlgorithm::GDALRasterSelectAlgorithm()        */
26
/************************************************************************/
27
28
GDALRasterSelectAlgorithm::GDALRasterSelectAlgorithm(bool standaloneStep)
29
0
    : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
30
0
                                      standaloneStep)
31
0
{
32
0
    {
33
0
        auto &arg =
34
0
            AddArg("band", 'b',
35
0
                   _("Band(s) (1-based index, 'mask' or 'mask:<band>')"),
36
0
                   &m_bands)
37
0
                .SetPositional()
38
0
                .SetRequired()
39
0
                .SetMinCount(1);
40
0
        arg.AddValidationAction(
41
0
            [&arg]()
42
0
            {
43
0
                const auto &val = arg.Get<std::vector<std::string>>();
44
0
                for (const auto &v : val)
45
0
                {
46
0
                    if (!STARTS_WITH(v.c_str(), "mask") &&
47
0
                        !(CPLGetValueType(v.c_str()) == CPL_VALUE_INTEGER &&
48
0
                          atoi(v.c_str()) >= 1))
49
0
                    {
50
0
                        CPLError(CE_Failure, CPLE_AppDefined,
51
0
                                 "Invalid band specification.");
52
0
                        return false;
53
0
                    }
54
0
                }
55
0
                return true;
56
0
            });
57
0
    }
58
0
    {
59
0
        auto &arg = AddArg(
60
0
            "mask", 0,
61
0
            _("Mask band (1-based index, 'mask', 'mask:<band>' or 'none')"),
62
0
            &m_mask);
63
0
        arg.AddValidationAction(
64
0
            [&arg]()
65
0
            {
66
0
                const auto &v = arg.Get<std::string>();
67
0
                if (!STARTS_WITH(v.c_str(), "mask") &&
68
0
                    !EQUAL(v.c_str(), "none") &&
69
0
                    !(CPLGetValueType(v.c_str()) == CPL_VALUE_INTEGER &&
70
0
                      atoi(v.c_str()) >= 1))
71
0
                {
72
0
                    CPLError(CE_Failure, CPLE_AppDefined,
73
0
                             "Invalid mask band specification.");
74
0
                    return false;
75
0
                }
76
0
                return true;
77
0
            });
78
0
    }
79
0
}
80
81
/************************************************************************/
82
/*                 GDALRasterSelectAlgorithm::RunStep()                 */
83
/************************************************************************/
84
85
bool GDALRasterSelectAlgorithm::RunStep(GDALPipelineStepRunContext &)
86
0
{
87
0
    const auto poSrcDS = m_inputDataset[0].GetDatasetRef();
88
0
    CPLAssert(poSrcDS);
89
0
    CPLAssert(m_outputDataset.GetName().empty());
90
0
    CPLAssert(!m_outputDataset.GetDatasetRef());
91
92
0
    CPLStringList aosOptions;
93
0
    aosOptions.AddString("-of");
94
0
    aosOptions.AddString("VRT");
95
0
    for (const std::string &v : m_bands)
96
0
    {
97
0
        aosOptions.AddString("-b");
98
0
        aosOptions.AddString(CPLString(v).replaceAll(':', ',').c_str());
99
0
    }
100
0
    if (!m_mask.empty())
101
0
    {
102
0
        aosOptions.AddString("-mask");
103
0
        aosOptions.AddString(CPLString(m_mask).replaceAll(':', ',').c_str());
104
0
    }
105
106
0
    GDALTranslateOptions *psOptions =
107
0
        GDALTranslateOptionsNew(aosOptions.List(), nullptr);
108
109
0
    auto poOutDS = std::unique_ptr<GDALDataset>(GDALDataset::FromHandle(
110
0
        GDALTranslate("", GDALDataset::ToHandle(poSrcDS), psOptions, nullptr)));
111
0
    GDALTranslateOptionsFree(psOptions);
112
0
    const bool bRet = poOutDS != nullptr;
113
0
    if (poOutDS)
114
0
    {
115
0
        m_outputDataset.Set(std::move(poOutDS));
116
0
    }
117
118
0
    return bRet;
119
0
}
120
121
0
GDALRasterSelectAlgorithmStandalone::~GDALRasterSelectAlgorithmStandalone() =
122
    default;
123
124
//! @endcond