Skip to content

Commit

Permalink
Merge pull request OSGeo#10979 from rouault/fix_10978
Browse files Browse the repository at this point in the history
JP2ECW: report JPEG2000 tile size as GDAL block size for ECW SDK >= 51 (up to 2048x2048 and dataset dimensions)
  • Loading branch information
rouault authored Oct 11, 2024
2 parents 62816a7 + 96c0616 commit 612810b
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
17 changes: 17 additions & 0 deletions autotest/gdrivers/ecw.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ def startup_and_cleanup():
else:
gdaltest.ecw_drv.major_version = 3
gdaltest.ecw_drv.minor_version = 3
gdaltest.ecw_drv.version = (
gdaltest.ecw_drv.major_version,
gdaltest.ecw_drv.minor_version,
)

# we set ECW to not resolve projection and datum strings to get 3.x behavior.
with gdal.config_option("ECW_DO_NOT_RESOLVE_DATUM_PROJECTION", "YES"):
Expand Down Expand Up @@ -2465,3 +2469,16 @@ def test_ecw_online_7():
expected_band_count,
ds.RasterCount,
)


###############################################################################
# Test reading a dataset whose tile dimensions are larger than dataset ones


def test_ecw_byte_tile_2048():

ds = gdal.Open("data/jpeg2000/byte_tile_2048.jp2")
(blockxsize, blockysize) = ds.GetRasterBand(1).GetBlockSize()
assert (blockxsize, blockysize) == (
(20, 20) if gdaltest.ecw_drv.version >= (5, 1) else (256, 256)
)
9 changes: 5 additions & 4 deletions autotest/gdrivers/nitf.py
Original file line number Diff line number Diff line change
Expand Up @@ -880,10 +880,11 @@ def test_nitf_28_jp2ecw(tmp_path):
blockxsize, blockysize = ds.GetRasterBand(1).GetBlockSize()
ds = None
gdal.Unlink(tmpfilename)
assert (blockxsize, blockysize) == (
256,
256,
) # 256 since this is hardcoded as such in the ECW driver
# 256 for ECW < 5.1, 1024 for ECW >= 5.1
assert (blockxsize, blockysize) == (256, 256) or (blockxsize, blockysize) == (
1024,
1024,
)
finally:
gdaltest.reregister_all_jpeg2000_drivers()

Expand Down
38 changes: 35 additions & 3 deletions frmts/ecw/ecwdataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "ecwdrivercore.h"

#include <algorithm>
#include <cmath>

#undef NOISY_DEBUG
Expand All @@ -33,7 +34,7 @@ static int bNCSInitialized = FALSE;

void ECWInitialize(void);

#define BLOCK_SIZE 256
constexpr int DEFAULT_BLOCK_SIZE = 256;

GDALDataset *ECWDatasetOpenJPEG2000(GDALOpenInfo *poOpenInfo);

Expand Down Expand Up @@ -71,8 +72,39 @@ ECWRasterBand::ECWRasterBand(ECWDataset *poDSIn, int nBandIn, int iOverviewIn,
nRasterXSize = poDS->GetRasterXSize() / (1 << (iOverview + 1));
nRasterYSize = poDS->GetRasterYSize() / (1 << (iOverview + 1));

nBlockXSize = BLOCK_SIZE;
nBlockYSize = BLOCK_SIZE;
#if ECWSDK_VERSION >= 51
if (poDSIn->bIsJPEG2000 && poDSIn->poFileView)
{
UINT32 nTileWidth = 0;
poDSIn->poFileView->GetParameter(
const_cast<char *>("JPC:DECOMPRESS:TILESIZE:X"), &nTileWidth);
if (nTileWidth <= static_cast<UINT32>(INT_MAX))
{
nBlockXSize = static_cast<int>(nTileWidth);
}
nBlockXSize = std::min(nBlockXSize, nRasterXSize);

UINT32 nTileHeight = 0;
poDSIn->poFileView->GetParameter(
const_cast<char *>("JPC:DECOMPRESS:TILESIZE:Y"), &nTileHeight);
if (nTileHeight <= static_cast<UINT32>(INT_MAX))
{
nBlockYSize = static_cast<int>(nTileHeight);
}
nBlockYSize = std::min(nBlockYSize, nRasterYSize);
}
#endif

// Slightly arbitrary value. Too large values would defeat the purpose
// of the block concept.
constexpr int LIMIT_FOR_BLOCK_SIZE = 2048;
if (nBlockXSize <= 0 || nBlockYSize <= 0 ||
nBlockXSize > LIMIT_FOR_BLOCK_SIZE ||
nBlockYSize > LIMIT_FOR_BLOCK_SIZE)
{
nBlockXSize = DEFAULT_BLOCK_SIZE;
nBlockYSize = DEFAULT_BLOCK_SIZE;
}

/* -------------------------------------------------------------------- */
/* Work out band color interpretation. */
Expand Down

0 comments on commit 612810b

Please sign in to comment.