diff --git a/autotest/gdrivers/ecw.py b/autotest/gdrivers/ecw.py index 0eaac23100a0..5f30e196ef97 100755 --- a/autotest/gdrivers/ecw.py +++ b/autotest/gdrivers/ecw.py @@ -117,7 +117,7 @@ def test_ecw_2(): if gdaltest.ecw_drv.major_version == 3: (exp_mean, exp_stddev) = (141.172, 67.3636) else: - if gdaltest.ecw_drv.major_version == 5: + if gdaltest.ecw_drv.major_version == 5 or gdaltest.ecw_drv.major_version == 6: (exp_mean, exp_stddev) = (141.606, 67.2919) else: (exp_mean, exp_stddev) = (140.332, 67.611) @@ -165,7 +165,7 @@ def test_ecw_4(tmp_path): if gdaltest.ecw_drv.major_version == 3: (exp_mean, exp_stddev) = (140.290, 66.6303) else: - if gdaltest.ecw_drv.major_version == 5: + if gdaltest.ecw_drv.major_version == 5 or gdaltest.ecw_drv.major_version == 6: (exp_mean, exp_stddev) = (141.517, 67.1285) else: (exp_mean, exp_stddev) = (138.971, 67.716) @@ -635,7 +635,7 @@ def test_ecw_20(): if gdaltest.ecw_drv.major_version == 3: (exp_mean, exp_stddev) = (141.644, 67.2186) else: - if gdaltest.ecw_drv.major_version == 5: + if gdaltest.ecw_drv.major_version == 5 or gdaltest.ecw_drv.major_version == 6: (exp_mean, exp_stddev) = (142.189, 62.4223) else: (exp_mean, exp_stddev) = (140.889, 62.742) @@ -669,7 +669,7 @@ def test_ecw_21(): if gdaltest.ecw_drv.major_version == 3: (exp_mean, exp_stddev) = (141.172, 67.3636) else: - if gdaltest.ecw_drv.major_version == 5: + if gdaltest.ecw_drv.major_version == 5 or gdaltest.ecw_drv.major_version == 6: (exp_mean, exp_stddev) = (141.606, 67.2919) else: (exp_mean, exp_stddev) = (140.332, 67.611) @@ -1933,6 +1933,14 @@ def test_ecw_44(): ("USE_SOP", "FALSE"), ] + # Modify expected PRECINCT_SIZE_X and PRECINCT_SIZE_Y for ECW SDK 6.x + if gdaltest.ecw_drv.major_version == 6: + for i, (key, value) in enumerate(expected_md): + if key == "PRECINCT_SIZE_X": + expected_md[i] = (key, "64,128,128") + elif key == "PRECINCT_SIZE_Y": + expected_md[i] = (key, "64,128,128") + got_md = ds.GetMetadata("JPEG2000") for (key, value) in expected_md: assert key in got_md and got_md[key] == value @@ -1949,6 +1957,8 @@ def RemoveDriverMetadata(md): del md["COLORSPACE"] if "VERSION" in md: del md["VERSION"] + if "ALL_COMMENTS" in md: + del md["ALL_COMMENTS"] return md @@ -1973,65 +1983,67 @@ def test_ecw_45(): src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) src_ds.SetMetadataItem("FOO", "BAR") out_ds = gdaltest.jp2ecw_drv.CreateCopy( - "/vsimem/ecw_45.jp2", src_ds, options=options + "/vsimem/ecw_45_1.jp2", src_ds, options=options ) del out_ds - assert gdal.VSIStatL("/vsimem/ecw_45.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/ecw_45.jp2") + assert gdal.VSIStatL("/vsimem/ecw_45_1.jp2.aux.xml") is None + + ds = gdal.Open("/vsimem/ecw_45_1.jp2") + md = RemoveDriverMetadata(ds.GetMetadata()) assert md == {"FOO": "BAR"} - gdal.Unlink("/vsimem/ecw_45.jp2") + gdal.Unlink("/vsimem/ecw_45_1.jp2") # Simple metadata in auxiliary domain src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) src_ds.SetMetadataItem("FOO", "BAR", "SOME_DOMAIN") out_ds = gdaltest.jp2ecw_drv.CreateCopy( - "/vsimem/ecw_45.jp2", src_ds, options=["WRITE_METADATA=YES"] + "/vsimem/ecw_45_2.jp2", src_ds, options=["WRITE_METADATA=YES"] ) del out_ds - assert gdal.VSIStatL("/vsimem/ecw_45.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/ecw_45.jp2") + assert gdal.VSIStatL("/vsimem/ecw_45_2.jp2.aux.xml") is None + ds = gdal.Open("/vsimem/ecw_45_2.jp2") md = RemoveDriverMetadata(ds.GetMetadata("SOME_DOMAIN")) assert md == {"FOO": "BAR"} - gdal.Unlink("/vsimem/ecw_45.jp2") + gdal.Unlink("/vsimem/ecw_45_2.jp2") # Simple metadata in auxiliary XML domain src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) src_ds.SetMetadata([""], "xml:SOME_DOMAIN") out_ds = gdaltest.jp2ecw_drv.CreateCopy( - "/vsimem/ecw_45.jp2", src_ds, options=["WRITE_METADATA=YES"] + "/vsimem/ecw_45_3.jp2", src_ds, options=["WRITE_METADATA=YES"] ) del out_ds - assert gdal.VSIStatL("/vsimem/ecw_45.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/ecw_45.jp2") + assert gdal.VSIStatL("/vsimem/ecw_45_3.jp2.aux.xml") is None + ds = gdal.Open("/vsimem/ecw_45_3.jp2") assert ds.GetMetadata("xml:SOME_DOMAIN")[0] == "\n" - gdal.Unlink("/vsimem/ecw_45.jp2") + gdal.Unlink("/vsimem/ecw_45_3.jp2") # Special xml:BOX_ metadata domain for options in [["WRITE_METADATA=YES"]]: src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) src_ds.SetMetadata([""], "xml:BOX_1") out_ds = gdaltest.jp2ecw_drv.CreateCopy( - "/vsimem/ecw_45.jp2", src_ds, options=options + "/vsimem/ecw_45_4.jp2", src_ds, options=options ) del out_ds - assert gdal.VSIStatL("/vsimem/ecw_45.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/ecw_45.jp2") + assert gdal.VSIStatL("/vsimem/ecw_45_4.jp2.aux.xml") is None + ds = gdal.Open("/vsimem/ecw_45_4.jp2") assert ds.GetMetadata("xml:BOX_0")[0] == "" - gdal.Unlink("/vsimem/ecw_45.jp2") + gdal.Unlink("/vsimem/ecw_45_4.jp2") # Special xml:XMP metadata domain for options in [["WRITE_METADATA=YES"]]: src_ds = gdal.GetDriverByName("MEM").Create("", 2, 2) src_ds.SetMetadata([""], "xml:XMP") out_ds = gdaltest.jp2ecw_drv.CreateCopy( - "/vsimem/ecw_45.jp2", src_ds, options=options + "/vsimem/ecw_45_5.jp2", src_ds, options=options ) del out_ds - assert gdal.VSIStatL("/vsimem/ecw_45.jp2.aux.xml") is None - ds = gdal.Open("/vsimem/ecw_45.jp2") + assert gdal.VSIStatL("/vsimem/ecw_45_5.jp2.aux.xml") is None + ds = gdal.Open("/vsimem/ecw_45_5.jp2") assert ds.GetMetadata("xml:XMP")[0] == "" - gdal.Unlink("/vsimem/ecw_45.jp2") + gdal.Unlink("/vsimem/ecw_45_5.jp2") ############################################################################### @@ -2107,7 +2119,7 @@ def test_ecw_47(): mean_tolerance = 0.5 - if gdaltest.ecw_drv.major_version == 5: + if gdaltest.ecw_drv.major_version == 5 or gdaltest.ecw_drv.major_version == 6: (exp_mean, exp_stddev) = (141.606, 67.2919) elif gdaltest.ecw_drv.major_version == 4: (exp_mean, exp_stddev) = (140.332, 67.611) @@ -2355,7 +2367,9 @@ def test_ecw_online_4(): if gdaltest.jp2ecw_drv is None: pytest.skip() - if gdaltest.ecw_drv.major_version == 5 and gdaltest.ecw_drv.minor_version == 2: + if ( + gdaltest.ecw_drv.major_version == 5 and gdaltest.ecw_drv.minor_version == 2 + ) or gdaltest.ecw_drv.major_version >= 6: pytest.skip("This test hangs on Linux in a mutex in the SDK 5.2.1") gdaltest.download_or_skip( @@ -2403,7 +2417,7 @@ def test_ecw_online_5(): mean_tolerance = 1 else: mean_tolerance = 0.5 - if gdaltest.ecw_drv.major_version == 5: + if gdaltest.ecw_drv.major_version == 5 or gdaltest.ecw_drv.major_version == 6: (exp_mean, exp_stddev) = (113.345, 52.1259) else: (exp_mean, exp_stddev) = (114.337, 52.1751) diff --git a/frmts/ecw/ecwcreatecopy.cpp b/frmts/ecw/ecwcreatecopy.cpp index 525bb65d9ad6..d5ff8b4b3f9e 100644 --- a/frmts/ecw/ecwcreatecopy.cpp +++ b/frmts/ecw/ecwcreatecopy.cpp @@ -814,6 +814,86 @@ CPLErr GDALECWCompressor::Initialize( if (bIsJPEG2000) { +#if ECWSDK_VERSION >= 60 + + pszOption = CSLFetchNameValue(papszOptions, "PROFILE"); + if (pszOption != nullptr && EQUAL(pszOption, "BASELINE_0")) + parameters->jp2.compress.SetProfile( + NCS::JPC::CJPC::Profile::BASELINE_0); + else if (pszOption != nullptr && EQUAL(pszOption, "BASELINE_1")) + parameters->jp2.compress.SetProfile( + NCS::JPC::CJPC::Profile::BASELINE_1); + else if (pszOption != nullptr && EQUAL(pszOption, "BASELINE_2")) + parameters->jp2.compress.SetProfile( + NCS::JPC::CJPC::Profile::BASELINE_2); + else if (pszOption != nullptr && EQUAL(pszOption, "NPJE")) + parameters->jp2.compress.SetProfile( + NCS::JPC::CJPC::Profile::NITF_BIIF_NPJE); + else if (pszOption != nullptr && EQUAL(pszOption, "EPJE")) + parameters->jp2.compress.SetProfile( + NCS::JPC::CJPC::Profile::NITF_BIIF_EPJE); + + pszOption = CSLFetchNameValue(papszOptions, "CODESTREAM_ONLY"); + if (pszOption == nullptr && EQUAL(CPLGetExtension(pszFilename), "j2k")) + pszOption = "YES"; + if (pszOption != nullptr) + parameters->jp2.compress.SetWriteCodestreamOnly( + CPLTestBool(pszOption)); + + pszOption = CSLFetchNameValue(papszOptions, "LEVELS"); + if (pszOption != nullptr) + parameters->jp2.compress.SetLevels((UINT32)atoi(pszOption)); + + pszOption = CSLFetchNameValue(papszOptions, "LAYERS"); + if (pszOption != nullptr) + parameters->jp2.compress.SetLayers((UINT32)atoi(pszOption)); + + pszOption = CSLFetchNameValue(papszOptions, "PRECINCT_WIDTH"); + UINT32 width = 0; + UINT32 height = 0; + if (pszOption != nullptr) + { + width = (UINT32)atoi(pszOption); + + pszOption = CSLFetchNameValue(papszOptions, "PRECINCT_HEIGHT"); + if (pszOption != nullptr) + { + height = (UINT32)atoi(pszOption); + parameters->jp2.compress.SetPrecinctDimensions(width, height); + } + } + pszOption = CSLFetchNameValue(papszOptions, "TILE_WIDTH"); + if (pszOption != nullptr) + { + width = (UINT32)atoi(pszOption); + + pszOption = CSLFetchNameValue(papszOptions, "TILE_HEIGHT"); + if (pszOption != nullptr) + { + height = (UINT32)atoi(pszOption); + parameters->jp2.compress.SetTileDimensions(width, height); + } + } + + pszOption = CSLFetchNameValue(papszOptions, "INCLUDE_SOP"); + if (pszOption != nullptr) + parameters->jp2.compress.SetIncludeSOP(CPLTestBool(pszOption)); + + pszOption = CSLFetchNameValue(papszOptions, "INCLUDE_EPH"); + if (pszOption != nullptr) + parameters->jp2.compress.SetIncludeEPH(CPLTestBool(pszOption)); + + pszOption = CSLFetchNameValue(papszOptions, "PROGRESSION"); + if (pszOption != nullptr && EQUAL(pszOption, "LRCP")) + parameters->jp2.compress.SetPrecinctProgressionOrder( + NCS::JPC::CProgressionOrderType::Type::LRCP); + else if (pszOption != nullptr && EQUAL(pszOption, "RLCP")) + parameters->jp2.compress.SetPrecinctProgressionOrder( + NCS::JPC::CProgressionOrderType::Type::RLCP); + else if (pszOption != nullptr && EQUAL(pszOption, "RPCL")) + parameters->jp2.compress.SetPrecinctProgressionOrder( + NCS::JPC::CProgressionOrderType::Type::RPCL); +#else pszOption = CSLFetchNameValue(papszOptions, "PROFILE"); if (pszOption != nullptr && EQUAL(pszOption, "BASELINE_0")) SetParameter(CNCSJP2FileView::JP2_COMPRESS_PROFILE_BASELINE_0); @@ -882,6 +962,7 @@ CPLErr GDALECWCompressor::Initialize( else if (pszOption != nullptr && EQUAL(pszOption, "RPCL")) SetParameter(CNCSJP2FileView::JP2_COMPRESS_PROGRESSION_RPCL); +#endif pszOption = CSLFetchNameValue(papszOptions, "GEODATA_USAGE"); if (pszOption == nullptr) @@ -900,6 +981,19 @@ CPLErr GDALECWCompressor::Initialize( else if (EQUAL(pszOption, "ALL")) SetGeodataUsage(JP2_GEODATA_USE_GML_PCS_WLD); +#if ECWSDK_VERSION >= 60 + pszOption = CSLFetchNameValue(papszOptions, "DECOMPRESS_LAYERS"); + if (pszOption != nullptr) + parameters->jp2.decompress.SetLayersToDecode( + (UINT32)atoi(pszOption)); + + pszOption = CSLFetchNameValue(papszOptions, + "DECOMPRESS_RECONSTRUCTION_PARAMETER"); + if (pszOption != nullptr) + parameters->jp2.decompress.SetReconstructionParameter( + (IEEE4)CPLAtof(pszOption)); + +#else pszOption = CSLFetchNameValue(papszOptions, "DECOMPRESS_LAYERS"); if (pszOption != nullptr) SetParameter(CNCSJP2FileView::JP2_DECOMPRESS_LAYERS, @@ -911,6 +1005,7 @@ CPLErr GDALECWCompressor::Initialize( SetParameter( CNCSJP2FileView::JPC_DECOMPRESS_RECONSTRUCTION_PARAMETER, (IEEE4)CPLAtof(pszOption)); +#endif } /* -------------------------------------------------------------------- */ diff --git a/frmts/ecw/ecwdataset.cpp b/frmts/ecw/ecwdataset.cpp index 933c07eb4149..73f236371f4a 100644 --- a/frmts/ecw/ecwdataset.cpp +++ b/frmts/ecw/ecwdataset.cpp @@ -2969,14 +2969,180 @@ GDALDataset *ECWDataset::Open(GDALOpenInfo *poOpenInfo, int bIsJPEG2000) poDS->GDALDataset::SetMetadataItem( "COLORSPACE", ECWGetColorSpaceName(poDS->psFileInfo->eColorSpace)); #if ECWSDK_VERSION >= 50 - if (!bIsJPEG2000) - poDS->GDALDataset::SetMetadataItem( - "VERSION", - CPLString().Printf("%d", poDS->psFileInfo->nFormatVersion)); + // Allow writing VERSION for JP2 also + //if (!bIsJPEG2000) + poDS->GDALDataset::SetMetadataItem( + "VERSION", CPLString().Printf("%d", poDS->psFileInfo->nFormatVersion)); #if ECWSDK_VERSION >= 51 // output jp2 header info if (bIsJPEG2000 && poDS->poFileView) { +#if ECWSDK_VERSION >= 60 + NCS::CString comments = poDS->poFileView->metadata->jp2.Comments(); + if (!comments.empty()) + { + poDS->SetMetadataItem( + "ALL_COMMENTS", CPLString().Printf("%s", comments.utf8_str())); + } + + // Profile + UINT32 nProfile = 2; + UINT16 nRsiz = poDS->poFileView->metadata->jp2.ComplianceProfileType(); + if (nRsiz == 0) + nProfile = 2; // Profile 2 (no restrictions) + else if (nRsiz == 1) + nProfile = 0; // Profile 0 + else if (nRsiz == 2) + nProfile = 1; // Profile 1, NITF_BIIF_NPJE, NITF_BIIF_EPJE + poDS->SetMetadataItem("PROFILE", CPLString().Printf("%d", nProfile), + JPEG2000_DOMAIN_NAME); + + // number of tiles on X axis + UINT32 nTileNrX = poDS->poFileView->metadata->jp2.NumberOfTiles().x; + poDS->SetMetadataItem("TILES_X", CPLString().Printf("%d", nTileNrX), + JPEG2000_DOMAIN_NAME); + + // number of tiles on X axis + UINT32 nTileNrY = poDS->poFileView->metadata->jp2.NumberOfTiles().y; + poDS->SetMetadataItem("TILES_Y", CPLString().Printf("%d", nTileNrY), + JPEG2000_DOMAIN_NAME); + + // Tile Width + UINT32 nTileSizeX = poDS->poFileView->metadata->jp2.TileSize().width; + poDS->SetMetadataItem("TILE_WIDTH", + CPLString().Printf("%d", nTileSizeX), + JPEG2000_DOMAIN_NAME); + + // Tile Height + UINT32 nTileSizeY = poDS->poFileView->metadata->jp2.TileSize().height; + poDS->SetMetadataItem("TILE_HEIGHT", + CPLString().Printf("%d", nTileSizeY), + JPEG2000_DOMAIN_NAME); + + // Precinct Sizes on X,Y axis + std::vector Precinctdim = + poDS->poFileView->metadata->jp2.PrecinctSize(); + + if (!Precinctdim.empty()) + { + std::string sX = std::to_string(Precinctdim[0].width); + std::string sY = std::to_string(Precinctdim[0].height); + for (std::size_t i = 1; i < Precinctdim.size(); ++i) + { + std::string stempX = std::to_string(Precinctdim[i].width); + std::string stempY = std::to_string(Precinctdim[i].height); + sX += "," + stempX; + sY += "," + stempY; + } + char const *csPreSizeX = sX.c_str(); + char const *csPreSizeY = sY.c_str(); + poDS->SetMetadataItem("PRECINCT_SIZE_X", csPreSizeX, + JPEG2000_DOMAIN_NAME); + poDS->SetMetadataItem("PRECINCT_SIZE_Y", csPreSizeY, + JPEG2000_DOMAIN_NAME); + } + + // Code Block Size on X axis + UINT32 nCodeBlockSizeX = + poDS->poFileView->metadata->jp2.CodeBlock().width; + poDS->SetMetadataItem("CODE_BLOCK_SIZE_X", + CPLString().Printf("%d", nCodeBlockSizeX), + JPEG2000_DOMAIN_NAME); + + // Code Block Size on Y axis + UINT32 nCodeBlockSizeY = + poDS->poFileView->metadata->jp2.CodeBlock().height; + poDS->SetMetadataItem("CODE_BLOCK_SIZE_Y", + CPLString().Printf("%d", nCodeBlockSizeY), + JPEG2000_DOMAIN_NAME); + + // Bitdepth + std::vector BitdepthList = + poDS->poFileView->metadata->jp2.BitDepth(); + + if (!BitdepthList.empty()) + { + std::string sbitdepth = std::to_string(BitdepthList[0]); + + for (std::size_t i = 1; i < BitdepthList.size(); ++i) + { + std::string stempbitdepth = std::to_string(BitdepthList[i]); + sbitdepth += "," + stempbitdepth; + } + char const *csBitdepth = sbitdepth.c_str(); + poDS->SetMetadataItem("PRECISION", csBitdepth, + JPEG2000_DOMAIN_NAME); + } + + // Resolution Levels + UINT32 nLevels = poDS->poFileView->metadata->jp2.Levels(); + poDS->SetMetadataItem("RESOLUTION_LEVELS", + CPLString().Printf("%d", nLevels), + JPEG2000_DOMAIN_NAME); + + // Quality Layers + UINT32 nLayers = poDS->poFileView->metadata->jp2.Layers(); + poDS->SetMetadataItem("QUALITY_LAYERS", + CPLString().Printf("%d", nLayers), + JPEG2000_DOMAIN_NAME); + + // Progression Order + NCS::JPC::CProgressionOrderType::Type orderType = + poDS->poFileView->metadata->jp2.PrecinctProgressionOrder(); + + const char *csOrder = nullptr; + switch (orderType) + { + case NCS::JPC::CProgressionOrderType::Type::LRCP: + csOrder = "LRCP"; + break; + case NCS::JPC::CProgressionOrderType::Type::RLCP: + csOrder = "RLCP"; + break; + case NCS::JPC::CProgressionOrderType::Type::RPCL: + csOrder = "RPCL"; + break; + case NCS::JPC::CProgressionOrderType::Type::PCRL: + csOrder = "PCRL"; + break; + case NCS::JPC::CProgressionOrderType::Type::CPRL: + csOrder = "CPRL"; + break; + } + if (csOrder) + { + poDS->SetMetadataItem("PROGRESSION_ORDER", csOrder, + JPEG2000_DOMAIN_NAME); + } + + // DWT Filter + const char *csFilter = nullptr; + NCS::JPC::CCodingStyleParameter::TransformationType tranformationType = + poDS->poFileView->metadata->jp2.TransformationType(); + if (tranformationType == + NCS::JPC::CCodingStyleParameter::TransformationType::REVERSIBLE_5x3) + csFilter = "5x3"; + else + csFilter = "9x7"; + poDS->SetMetadataItem("TRANSFORMATION_TYPE", csFilter, + JPEG2000_DOMAIN_NAME); + + // SOP used? + bool bSOP = poDS->poFileView->metadata->jp2.SOPExists(); + poDS->SetMetadataItem("USE_SOP", (bSOP) ? "TRUE" : "FALSE", + JPEG2000_DOMAIN_NAME); + + // EPH used? + bool bEPH = poDS->poFileView->metadata->jp2.EPHExists(); + poDS->SetMetadataItem("USE_EPH", (bEPH) ? "TRUE" : "FALSE", + JPEG2000_DOMAIN_NAME); + + // GML JP2 data contained? + bool bGML = poDS->poFileView->metadata->jp2.GMLJP2BoxExists(); + poDS->SetMetadataItem("GML_JP2_DATA", (bGML) ? "TRUE" : "FALSE", + JPEG2000_DOMAIN_NAME); + +#else // comments char *csComments = nullptr; poDS->poFileView->GetParameter((char *)"JPC:DECOMPRESS:COMMENTS", @@ -3130,7 +3296,7 @@ GDALDataset *ECWDataset::Open(GDALOpenInfo *poOpenInfo, int bIsJPEG2000) CPLString().Printf("%d", nLevels), JPEG2000_DOMAIN_NAME); - // Qualaity Layers + // Quality Layers UINT32 nLayers = 0; poDS->poFileView->GetParameter((char *)"JP2:DECOMPRESS:LAYERS", &nLayers); @@ -3180,6 +3346,7 @@ GDALDataset *ECWDataset::Open(GDALOpenInfo *poOpenInfo, int bIsJPEG2000) poDS->poFileView->GetParameter((char *)"JP2:GML:JP2:BOX:EXISTS", &bGML); poDS->SetMetadataItem("GML_JP2_DATA", (bGML) ? "TRUE" : "FALSE", JPEG2000_DOMAIN_NAME); +#endif //ECWSDK_VERSION>=60 } #endif // ECWSDK_VERSION>=51 if (!bIsJPEG2000 && poDS->psFileInfo->nFormatVersion >= 3) @@ -3709,10 +3876,19 @@ void ECWInitialize() /* the toolkit. */ /* -------------------------------------------------------------------- */ if (!CPLTestBool(CPLGetConfigOption("CONVERT_YCBCR_TO_RGB", "YES"))) +#if ECWSDK_VERSION >= 60 + NCS::SDK::CFileBase::sConfig().SetManageICC(false); +#else NCSecwSetConfig(NCSCFG_JP2_MANAGE_ICC, FALSE); +#endif #if ECWSDK_VERSION >= 50 +#if ECWSDK_VERSION >= 60 + NCS::SDK::CFileBase::sConfig().SetEcwpClientHttpUserAgent( + "ECW GDAL Driver/" NCS_ECWJP2_FULL_VERSION_STRING_DOT_DEL); +#else NCSecwSetConfig(NCSCFG_ECWP_CLIENT_HTTP_USER_AGENT, "ECW GDAL Driver/" NCS_ECWJP2_FULL_VERSION_STRING_DOT_DEL); +#endif #endif /* -------------------------------------------------------------------- */ /* Initialize cache memory limit. Default is apparently 1/4 RAM. */ @@ -3723,7 +3899,12 @@ void ECWInitialize() pszEcwCacheSize = CPLGetConfigOption("ECW_CACHE_MAXMEM", nullptr); if (pszEcwCacheSize != nullptr) +#if ECWSDK_VERSION >= 60 + NCS::SDK::CFileBase::sConfig().SetCacheMaxmem( + (UINT64)atoi(pszEcwCacheSize)); +#else NCSecwSetConfig(NCSCFG_CACHE_MAXMEM, (UINT32)atoi(pszEcwCacheSize)); +#endif /* -------------------------------------------------------------------- */ /* Version 3.x and 4.x of the ECWJP2 SDK did not resolve datum and */ @@ -3734,8 +3915,13 @@ void ECWInitialize() #if ECWSDK_VERSION >= 50 if (CPLTestBool(CPLGetConfigOption("ECW_DO_NOT_RESOLVE_DATUM_PROJECTION", "NO")) == TRUE) +#if ECWSDK_VERSION >= 60 + NCS::SDK::CFileBase::sConfig().SetProjectionFormat( + NCS_PROJECTION_ERMAPPER_FORMAT); +#else NCSecwSetConfig(NCSCFG_PROJECTION_FORMAT, NCS_PROJECTION_ERMAPPER_FORMAT); +#endif #endif /* -------------------------------------------------------------------- */ /* Allow configuration of a local cache based on configuration */ @@ -3747,19 +3933,55 @@ void ECWInitialize() #if ECWSDK_VERSION >= 40 pszOpt = CPLGetConfigOption("ECWP_CACHE_SIZE_MB", nullptr); if (pszOpt) +#if ECWSDK_VERSION >= 60 + NCS::SDK::CFileBase::sConfig().SetEcwpCacheSizeMb((INT32)atoi(pszOpt)); +#else NCSecwSetConfig(NCSCFG_ECWP_CACHE_SIZE_MB, (INT32)atoi(pszOpt)); +#endif pszOpt = CPLGetConfigOption("ECWP_CACHE_LOCATION", nullptr); if (pszOpt) { +#if ECWSDK_VERSION >= 60 + NCS::SDK::CFileBase::sConfig().SetEcwpCacheLocation(pszOpt); + NCS::SDK::CFileBase::sConfig().SetEcwpCacheEnabled(true); +#else NCSecwSetConfig(NCSCFG_ECWP_CACHE_LOCATION, pszOpt); NCSecwSetConfig(NCSCFG_ECWP_CACHE_ENABLED, (BOOLEAN)TRUE); - } #endif + } +#endif //ECWSDK_VERSION >=40 /* -------------------------------------------------------------------- */ /* Various other configuration items. */ /* -------------------------------------------------------------------- */ +#if ECWSDK_VERSION >= 60 + pszOpt = CPLGetConfigOption("ECWP_BLOCKING_TIME_MS", nullptr); + if (pszOpt) + NCS::SDK::CFileBase::sConfig().SetBlockingTimeMS( + (NCSTimeStampMs)atoi(pszOpt)); + + // I believe 10s means we wait for complete data back from + // ECWP almost all the time which is good for our blocking model. + pszOpt = CPLGetConfigOption("ECWP_REFRESH_TIME_MS", "10000"); + if (pszOpt) + NCS::SDK::CFileBase::sConfig().SetRefreshTimeMS( + (NCSTimeStampMs)atoi(pszOpt)); + + pszOpt = CPLGetConfigOption("ECW_TEXTURE_DITHER", nullptr); + if (pszOpt) + NCS::SDK::CFileBase::sConfig().SetTextureDitherEnabled( + CPLTestBool(pszOpt)); + + pszOpt = CPLGetConfigOption("ECW_FORCE_FILE_REOPEN", nullptr); + if (pszOpt) + NCS::SDK::CFileBase::sConfig().SetForceFileReopen(CPLTestBool(pszOpt)); + + pszOpt = CPLGetConfigOption("ECW_CACHE_MAXOPEN", nullptr); + if (pszOpt) + NCS::SDK::CFileBase::sConfig().SetCacheMaxopen((UINT32)atoi(pszOpt)); + +#else pszOpt = CPLGetConfigOption("ECWP_BLOCKING_TIME_MS", nullptr); if (pszOpt) NCSecwSetConfig(NCSCFG_BLOCKING_TIME_MS, (NCSTimeStampMs)atoi(pszOpt)); @@ -3781,8 +4003,21 @@ void ECWInitialize() pszOpt = CPLGetConfigOption("ECW_CACHE_MAXOPEN", nullptr); if (pszOpt) NCSecwSetConfig(NCSCFG_CACHE_MAXOPEN, (UINT32)atoi(pszOpt)); +#endif #if ECWSDK_VERSION >= 40 +#if ECWSDK_VERSION >= 60 + pszOpt = CPLGetConfigOption("ECW_OPTIMIZE_USE_NEAREST_NEIGHBOUR", nullptr); + if (pszOpt) + NCS::SDK::CFileBase::sConfig().SetOptimizeUseNearestNeighbour( + CPLTestBool(pszOpt)); + + pszOpt = CPLGetConfigOption("ECW_RESILIENT_DECODING", nullptr); + if (pszOpt) + NCS::SDK::CFileBase::sConfig().SetResilientDecodingEnabled( + CPLTestBool(pszOpt)); + +#else pszOpt = CPLGetConfigOption("ECW_AUTOGEN_J2I", nullptr); if (pszOpt) NCSecwSetConfig(NCSCFG_JP2_AUTOGEN_J2I, (BOOLEAN)CPLTestBool(pszOpt)); @@ -3797,6 +4032,7 @@ void ECWInitialize() NCSecwSetConfig(NCSCFG_RESILIENT_DECODING, (BOOLEAN)CPLTestBool(pszOpt)); #endif +#endif } /************************************************************************/ diff --git a/frmts/ecw/gdal_ecw.h b/frmts/ecw/gdal_ecw.h index 70ec8ec3464d..26ee0f258fb2 100644 --- a/frmts/ecw/gdal_ecw.h +++ b/frmts/ecw/gdal_ecw.h @@ -1,4 +1,5 @@ /****************************************************************************** + * $Id$ * * Project: GDAL * Purpose: ECW (ERDAS Wavelet Compression Format) Driver Definitions @@ -646,8 +647,8 @@ class ECWRasterBand final : public GDALPamRasterBand #if ECWSDK_VERSION >= 50 - int nStatsBandIndex = 0; - int nStatsBandCount = 0; + int nStatsBandIndex{}; + int nStatsBandCount{}; #endif diff --git a/frmts/ecw/jp2userbox.cpp b/frmts/ecw/jp2userbox.cpp index e5effa0191d4..b2ff12b70aeb 100644 --- a/frmts/ecw/jp2userbox.cpp +++ b/frmts/ecw/jp2userbox.cpp @@ -87,7 +87,7 @@ CNCSError JP2UserBox::Parse(CPL_UNUSED class CNCSJP2File &JP2File, CPL_UNUSED CNCSJPCIOStream &Stream) #endif { - CNCSError Error(GetCNCSError(NCS_SUCCESS)); + CNCSError Error; return Error; }