From 57c35e8f00388edb77aed9c9b77ea20e29cb10e9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 18 Feb 2024 19:42:11 +0100 Subject: [PATCH] JP2OpenJPEG: CreateCopy(): limit number of resolutions taking into account minimum block width/height (fixes #9236) --- autotest/gdrivers/jp2openjpeg.py | 14 ++++++++++++++ frmts/openjpeg/openjpegdataset.cpp | 5 ++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/autotest/gdrivers/jp2openjpeg.py b/autotest/gdrivers/jp2openjpeg.py index 13e1dbbc1673..6496d761c0e4 100755 --- a/autotest/gdrivers/jp2openjpeg.py +++ b/autotest/gdrivers/jp2openjpeg.py @@ -3842,3 +3842,17 @@ def test_jp2openjpeg_reversible_quality_not_100(): ds = None gdaltest.jp2openjpeg_drv.Delete(filename) + + +############################################################################### +# Test fix for https://github.com/OSGeo/gdal/issues/9236 + + +def test_jp2openjpeg_limit_resolution_count_from_image_size(tmp_vsimem): + + filename = str(tmp_vsimem / "out.jp2") + assert gdal.Translate(filename, "data/byte.tif", width=1024, height=7) + + # Check number of resolutions + ret = gdal.GetJPEG2000StructureAsString(filename, ["ALL=YES"]) + assert '2' in ret diff --git a/frmts/openjpeg/openjpegdataset.cpp b/frmts/openjpeg/openjpegdataset.cpp index d0ff887ad035..7b24b8ec88e9 100644 --- a/frmts/openjpeg/openjpegdataset.cpp +++ b/frmts/openjpeg/openjpegdataset.cpp @@ -2725,9 +2725,11 @@ GDALDataset *JP2OpenJPEGDataset::CreateCopy( } const int nMaxTileDim = std::max(nBlockXSize, nBlockYSize); + const int nMinTileDim = std::min(nBlockXSize, nBlockYSize); int nNumResolutions = 1; /* Pickup a reasonable value compatible with PROFILE_1 requirements */ - while ((nMaxTileDim >> (nNumResolutions - 1)) > 128) + while ((nMaxTileDim >> (nNumResolutions - 1)) > 128 && + (nMinTileDim >> nNumResolutions) > 0) nNumResolutions++; int nMinProfile1Resolutions = nNumResolutions; const char *pszResolutions = @@ -2736,6 +2738,7 @@ GDALDataset *JP2OpenJPEGDataset::CreateCopy( { nNumResolutions = atoi(pszResolutions); if (nNumResolutions <= 0 || nNumResolutions >= 32 || + (nMinTileDim >> nNumResolutions) == 0 || (nMaxTileDim >> nNumResolutions) == 0) { CPLError(CE_Warning, CPLE_NotSupported,