Skip to content

Commit

Permalink
GDALAutoCreateWarpedVRT(): ignore src nodata value if it cannot be re…
Browse files Browse the repository at this point in the history
…presented in the source band data type
  • Loading branch information
rouault committed Sep 1, 2024
1 parent d1ac424 commit 6074893
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
14 changes: 14 additions & 0 deletions autotest/gdrivers/vrtwarp.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,3 +745,17 @@ def test_vrtwarp_autocreatewarpedvrt_int16_nodata_32767():
ds.GetRasterBand(1).SetNoDataValue(32767)
vrt_ds = gdal.AutoCreateWarpedVRT(ds)
assert vrt_ds.GetRasterBand(1).DataType == gdal.GDT_Int16


###############################################################################
# Test gdal.AutoCreateWarpedVRT() on a source nodata value that does not fit
# the source band type


def test_vrtwarp_autocreatewarpedvrt_invalid_nodata():

ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 1, gdal.GDT_Byte)
ds.SetGeoTransform([0, 1, 0, 0, 0, -1])
ds.GetRasterBand(1).SetNoDataValue(-9999)
vrt_ds = gdal.AutoCreateWarpedVRT(ds)
assert vrt_ds.GetRasterBand(1).DataType == gdal.GDT_Byte
49 changes: 36 additions & 13 deletions frmts/vrt/vrtwarped.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ GDALDatasetH CPL_STDCALL GDALAutoCreateWarpedVRTEx(
if (psWO->padfSrcNoDataReal == nullptr &&
psWO->padfDstNoDataReal == nullptr && psWO->nSrcAlphaBand == 0)
{
// If none of the provided input nodata values can be represented in the
// data type of the corresponding source band, ignore them.
int nCountInvalidSrcNoDataReal = 0;
for (int i = 0; i < psWO->nBandCount; i++)
{
GDALRasterBandH rasterBand =
Expand All @@ -189,22 +192,42 @@ GDALDatasetH CPL_STDCALL GDALAutoCreateWarpedVRTEx(
double noDataValue =
GDALGetRasterNoDataValue(rasterBand, &hasNoDataValue);

if (hasNoDataValue)
if (hasNoDataValue &&
!GDALIsValueExactAs(noDataValue,
GDALGetRasterDataType(rasterBand)))
{
// Check if the nodata value is out of range
int bClamped = FALSE;
int bRounded = FALSE;
CPL_IGNORE_RET_VAL(GDALAdjustValueToDataType(
GDALGetRasterDataType(rasterBand), noDataValue, &bClamped,
&bRounded));
if (!bClamped)
nCountInvalidSrcNoDataReal++;
}
}

if (nCountInvalidSrcNoDataReal != psWO->nBandCount)
{
for (int i = 0; i < psWO->nBandCount; i++)
{
GDALRasterBandH rasterBand =
GDALGetRasterBand(psWO->hSrcDS, psWO->panSrcBands[i]);

int hasNoDataValue;
double noDataValue =
GDALGetRasterNoDataValue(rasterBand, &hasNoDataValue);

if (hasNoDataValue)
{
GDALWarpInitNoDataReal(psWO, -1e10);
if (psWO->padfSrcNoDataReal != nullptr &&
psWO->padfDstNoDataReal != nullptr)
// Check if the nodata value is out of range
int bClamped = FALSE;
int bRounded = FALSE;
CPL_IGNORE_RET_VAL(GDALAdjustValueToDataType(
GDALGetRasterDataType(rasterBand), noDataValue,
&bClamped, &bRounded));
if (!bClamped)
{
psWO->padfSrcNoDataReal[i] = noDataValue;
psWO->padfDstNoDataReal[i] = noDataValue;
GDALWarpInitNoDataReal(psWO, -1e10);
if (psWO->padfSrcNoDataReal != nullptr &&
psWO->padfDstNoDataReal != nullptr)
{
psWO->padfSrcNoDataReal[i] = noDataValue;
psWO->padfDstNoDataReal[i] = noDataValue;
}
}
}
}
Expand Down

0 comments on commit 6074893

Please sign in to comment.