Coverage Report

Created: 2026-07-14 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_raster_resize.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  "resize" 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_resize.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
/*        GDALRasterResizeAlgorithm::GDALRasterResizeAlgorithm()        */
26
/************************************************************************/
27
28
GDALRasterResizeAlgorithm::GDALRasterResizeAlgorithm(bool standaloneStep)
29
0
    : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
30
0
                                      standaloneStep)
31
0
{
32
0
    AddArg("resolution", 0, _("Target resolution (in destination CRS units)"),
33
0
           &m_resolution)
34
0
        .SetMinCount(2)
35
0
        .SetMaxCount(2)
36
0
        .SetMinValueExcluded(0)
37
0
        .SetRepeatedArgAllowed(false)
38
0
        .SetDisplayHintAboutRepetition(false)
39
0
        .SetMetaVar("<xres>,<yres>")
40
0
        .SetMutualExclusionGroup("resolution-size");
41
42
    // The same logic is applied in gdalalg_raster_create.cpp
43
0
    AddArg("size", 0,
44
0
           _("Target size in pixels (or percentage if using '%' suffix)"),
45
0
           &m_size)
46
0
        .SetMinCount(2)
47
0
        .SetMaxCount(2)
48
0
        .SetRequired()
49
0
        .SetMinValueIncluded(0)
50
0
        .SetRepeatedArgAllowed(false)
51
0
        .SetDisplayHintAboutRepetition(false)
52
0
        .SetMetaVar("<width[%]>,<height[%]>")
53
0
        .SetMutualExclusionGroup("resolution-size")
54
0
        .AddValidationAction(
55
0
            [this]()
56
0
            {
57
0
                for (const auto &s : m_size)
58
0
                {
59
0
                    auto trimmed = cpl::trim(s);
60
0
                    if (!trimmed.empty() && trimmed.back() == '%')
61
0
                    {
62
0
                        trimmed = trimmed.substr(0, trimmed.size() - 1);
63
0
                    }
64
65
0
                    if (cpl::strict_parse<int>(trimmed).value_or(-1) < 0)
66
0
                    {
67
0
                        ReportError(CE_Failure, CPLE_IllegalArg,
68
0
                                    "Invalid size value: %s'", s.c_str());
69
0
                        return false;
70
0
                    }
71
0
                }
72
0
                return true;
73
0
            });
74
0
    AddArg("resampling", 'r', _("Resampling method"), &m_resampling)
75
0
        .SetChoices("nearest", "bilinear", "cubic", "cubicspline", "lanczos",
76
0
                    "average", "mode")
77
0
        .SetDefault("nearest")
78
0
        .SetHiddenChoices("near");
79
0
}
80
81
/************************************************************************/
82
/*                 GDALRasterResizeAlgorithm::RunStep()                 */
83
/************************************************************************/
84
85
bool GDALRasterResizeAlgorithm::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
    if (!m_size.empty())
96
0
    {
97
0
        aosOptions.AddString("-outsize");
98
0
        aosOptions.AddString(m_size[0]);
99
0
        aosOptions.AddString(m_size[1]);
100
0
    }
101
0
    if (!m_resolution.empty())
102
0
    {
103
0
        aosOptions.AddString("-tr");
104
0
        aosOptions.AddString(CPLSPrintf("%.17g", m_resolution[0]));
105
0
        aosOptions.AddString(CPLSPrintf("%.17g", m_resolution[1]));
106
0
    }
107
0
    if (!m_resampling.empty())
108
0
    {
109
0
        aosOptions.AddString("-r");
110
0
        aosOptions.AddString(m_resampling.c_str());
111
0
    }
112
113
0
    GDALTranslateOptions *psOptions =
114
0
        GDALTranslateOptionsNew(aosOptions.List(), nullptr);
115
116
0
    auto poOutDS = std::unique_ptr<GDALDataset>(GDALDataset::FromHandle(
117
0
        GDALTranslate("", GDALDataset::ToHandle(poSrcDS), psOptions, nullptr)));
118
0
    GDALTranslateOptionsFree(psOptions);
119
0
    const bool bRet = poOutDS != nullptr;
120
0
    if (poOutDS)
121
0
    {
122
0
        m_outputDataset.Set(std::move(poOutDS));
123
0
    }
124
125
0
    return bRet;
126
0
}
127
128
0
GDALRasterResizeAlgorithmStandalone::~GDALRasterResizeAlgorithmStandalone() =
129
    default;
130
131
//! @endcond