Skip to content

Commit

Permalink
NITF: properly take into account comma-separated list of values for J…
Browse files Browse the repository at this point in the history
…PEG2000 QUALITY

when JPEG2000_DRIVER=JP2OpenJPEG

Fixes #10927
  • Loading branch information
rouault committed Oct 4, 2024
1 parent 9660894 commit c09dd0f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 11 deletions.
15 changes: 15 additions & 0 deletions autotest/gdrivers/nitf.py
Original file line number Diff line number Diff line change
Expand Up @@ -986,9 +986,23 @@ def test_nitf_28_jp2openjpeg_bis(tmp_path):
createcopy=True,
)
ds = gdal.Open(filename)
size = os.stat(filename).st_size
assert ds.GetRasterBand(1).Checksum() in (31604, 31741)
ds = None

nitf_create(
filename,
["ICORDS=G", "IC=C8", "QUALITY=10,25"],
set_inverted_color_interp=False,
createcopy=True,
)
ds = gdal.Open(filename)
size2 = os.stat(filename).st_size
assert ds.GetRasterBand(1).Checksum() in (31604, 31741)
ds = None

assert size2 > size

tmpfilename = "/vsimem/nitf_28_jp2openjpeg_bis.ntf"
src_ds = gdal.GetDriverByName("MEM").Create("", 1025, 1025)
gdal.GetDriverByName("NITF").CreateCopy(tmpfilename, src_ds, options=["IC=C8"])
Expand Down Expand Up @@ -1100,6 +1114,7 @@ def test_nitf_jp2openjpeg_npje_numerically_lossless(tmp_vsimem):
"IC=C8",
"JPEG2000_DRIVER=JP2OpenJPEG",
"PROFILE=NPJE_NUMERICALLY_LOSSLESS",
"QUALITY=10,100",
],
)

Expand Down
6 changes: 4 additions & 2 deletions doc/source/drivers/raster/nitf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,12 @@ The following creation options are available:
CreateCopy() and/or Create() methods. See below paragraph for specificities.

- .. co:: QUALITY
:choices: 10-100
:default: 75

JPEG quality 10-100
For JPEG, quality as integer values in the 10-100 range
For JPEG2000, quality as a floating-point value in >0 - 100 range.
When JPEG2000_DRIVER=JP2OpenJPEG and PROFILE is not one of the NPJE ones,
several quality layers can be specified as a comma-separated list of values.

- .. co:: PROGRESSIVE
:choices: YES, NO
Expand Down
43 changes: 34 additions & 9 deletions frmts/nitf/nitfdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4018,8 +4018,15 @@ static char **NITFJP2OPENJPEGOptions(GDALDriver *poJ2KDriver,
{
char **papszJP2Options = CSLAddString(nullptr, "CODEC=J2K");

double dfQuality =
CPLAtof(CSLFetchNameValueDef(papszOptions, "QUALITY", "0"));
const char *pszQuality = CSLFetchNameValue(papszOptions, "QUALITY");
double dfQuality = 0;
if (pszQuality)
{
for (const char *pszVal :
CPLStringList(CSLTokenizeString2(pszQuality, ",", 0)))
dfQuality = std::max(dfQuality, CPLAtof(pszVal));
}

double dfTarget =
CPLAtof(CSLFetchNameValueDef(papszOptions, "TARGET", "0"));

Expand All @@ -4036,10 +4043,10 @@ static char **NITFJP2OPENJPEGOptions(GDALDriver *poJ2KDriver,
}

// Set it now before the NPJE profiles have a chance to override it
if (dfQuality > 0)
if (pszQuality)
{
papszJP2Options = CSLSetNameValue(papszJP2Options, "QUALITY",
CPLSPrintf("%f", dfQuality));
papszJP2Options =
CSLSetNameValue(papszJP2Options, "QUALITY", pszQuality);
}

const char *pszProfile = CSLFetchNameValueDef(papszOptions, "PROFILE", "");
Expand All @@ -4050,6 +4057,14 @@ static char **NITFJP2OPENJPEGOptions(GDALDriver *poJ2KDriver,
// (https://nsgreg.nga.mil/doc/view?i=2031&month=3&day=22&year=2021),
// for NPJE (Appendix D ) profile

if (pszQuality && strchr(pszQuality, ','))
{
CPLError(CE_Warning, CPLE_AppDefined,
"Only largest value of QUALITY used when PROFILE=%s "
"is specified",
pszProfile);
}

papszJP2Options =
CSLAddString(papszJP2Options, "@BLOCKSIZE_STRICT=YES");

Expand Down Expand Up @@ -7051,11 +7066,21 @@ void NITFDriver::InitCreationOptionList()
if (bHasJPEG2000Drivers)
osCreationOptions += " <Value>C8</Value>";

osCreationOptions +=
" </Option>"
osCreationOptions += " </Option>";

#if !defined(JPEG_SUPPORTED)
if (bHasJPEG2000Drivers)
#endif
{
osCreationOptions +=
" <Option name='QUALITY' type='string' "
"description='JPEG (10-100) or JPEG2000 quality, possibly as a"
"separated list of values for JPEG2000_DRIVER=JP2OPENJPEG' "
"default='75'/>";
}

#ifdef JPEG_SUPPORTED
" <Option name='QUALITY' type='int' description='JPEG quality "
"10-100' default='75'/>"
osCreationOptions +=
" <Option name='PROGRESSIVE' type='boolean' description='JPEG "
"progressive mode'/>"
" <Option name='RESTART_INTERVAL' type='int' description='Restart "
Expand Down

0 comments on commit c09dd0f

Please sign in to comment.