From e5cb5406ea9090b2f17cffeeb7ba5fb49e7158f2 Mon Sep 17 00:00:00 2001 From: Chris Tapley Date: Tue, 15 Oct 2019 17:19:14 +0800 Subject: [PATCH] ecwjp2 sdk 5.5 changes - implementation for API breaking changes. - handle "newabi" rename to "cpp11abi" in configure and configure.ac - example information in nmake.opt --- gdal/configure | 34 +++++--- gdal/configure.ac | 30 ++++--- gdal/frmts/ecw/ecwcreatecopy.cpp | 17 ++-- gdal/frmts/ecw/ecwdataset.cpp | 133 ++++++++++++++++--------------- gdal/frmts/ecw/gdal_ecw.h | 37 +++++---- gdal/frmts/ecw/jp2userbox.cpp | 21 +++-- gdal/nmake.opt | 35 ++++++-- 7 files changed, 185 insertions(+), 122 deletions(-) diff --git a/gdal/configure b/gdal/configure index 40d038394ed..fd2e3f6c12f 100755 --- a/gdal/configure +++ b/gdal/configure @@ -33205,18 +33205,23 @@ $as_echo "found libecwj2 in $with_ecw/lib." >&6; } # ECW SDK 5.0 style and also for the case where license type is included in path i.e. specific license type is requested. elif test -r $with_ecw/lib/$ECW_ARCH/$ECW_CONF/libNCSEcw.a ; then - # Test if we must use the newabi version (SDK 5.4) - if test -r $with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + # Test if we must use the newabi/cpp11abi version (SDK 5.4+) + if test -r $with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a || test -r $with_ecw/lib/cpp11abi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + if test -d $with_ecw/lib/newabi; then + ECW_ABIDIR=newabi + else + ECW_ABIDIR=cpp11abi + fi echo "#include " > testnewabi.cpp echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp echo "int main() { return static_cast(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp - if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then - ECW_LIBDIR=$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF + if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then + ECW_LIBDIR=$with_ecw/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA" with_ecw=$with_ecw/$ecw_license_type ECW_54="yes" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&5 -$as_echo "found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.4+ SDK with ${ECW_ABIDIR} in ${ECW_LIBDIR}." >&5 +$as_echo "found Intergraph 5.4+ SDK with ${ECW_ABIDIR} in ${ECW_LIBDIR}." >&6; } rm -f testnewabi.* rm -f testnewabi break @@ -33234,17 +33239,22 @@ $as_echo "found Intergraph 5.x+ SDK in ${ECW_LIBDIR}." >&6; } elif test -d $with_ecw; then for ecw_license_type in "Desktop_Read-Write" "Server_Read-Only_EndUser" "Server_Read-Only" "Server_Read-Write" "Desktop_Read-Only" do - # Test if we must use the newabi version (SDK 5.4) - if test -r $with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + # Test if we must use the newabi/cpp11abi version (SDK 5.4+) + if test -r $with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a || test -r $with_ecw/$ecw_license_type/lib/cpp11abi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + if test -d $with_ecw/lib/newabi; then + ECW_ABIDIR=newabi + else + ECW_ABIDIR=cpp11abi + fi echo "#include " > testnewabi.cpp echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp echo "int main() { return static_cast(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp - if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then - ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF + if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/$ecw_license_type/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then + ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA" with_ecw=$with_ecw/$ecw_license_type - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&5 -$as_echo "found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.4+ SDK with ${ECW_ABIDIR} in ${ECW_LIBDIR}." >&5 +$as_echo "found Intergraph 5.4+ SDK with ${ECW_ABIDIR} in ${ECW_LIBDIR}." >&6; } ECW_54="yes" rm -f testnewabi.* rm -f testnewabi diff --git a/gdal/configure.ac b/gdal/configure.ac index ce2618cd0fe..c46efad2543 100644 --- a/gdal/configure.ac +++ b/gdal/configure.ac @@ -3244,17 +3244,22 @@ else # ECW SDK 5.0 style and also for the case where license type is included in path i.e. specific license type is requested. elif test -r $with_ecw/lib/$ECW_ARCH/$ECW_CONF/libNCSEcw.a ; then - # Test if we must use the newabi version (SDK 5.4) - if test -r $with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + # Test if we must use the newabi/cpp11abi version (SDK 5.4+) + if test -r $with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a || test -r $with_ecw/lib/cpp11abi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + if test -d $with_ecw/lib/newabi; then + ECW_ABIDIR=newabi + else + ECW_ABIDIR=cpp11abi + fi echo "#include " > testnewabi.cpp echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp echo "int main() { return static_cast(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp - if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then - ECW_LIBDIR=$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF + if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then + ECW_LIBDIR=$with_ecw/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA" with_ecw=$with_ecw/$ecw_license_type ECW_54="yes" - AC_MSG_RESULT([found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}.]) + AC_MSG_RESULT([found Intergraph 5.4+ SDK with ${ECW_ABIDIR} in ${ECW_LIBDIR}.]) rm -f testnewabi.* rm -f testnewabi break @@ -3271,16 +3276,21 @@ else elif test -d $with_ecw; then for ecw_license_type in "Desktop_Read-Write" "Server_Read-Only_EndUser" "Server_Read-Only" "Server_Read-Write" "Desktop_Read-Only" do - # Test if we must use the newabi version (SDK 5.4) - if test -r $with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + # Test if we must use the newabi/cpp11abi version (SDK 5.4+) + if test -r $with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a || test -r $with_ecw/$ecw_license_type/lib/cpp11abi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then + if test -d $with_ecw/lib/newabi; then + ECW_ABIDIR=newabi + else + ECW_ABIDIR=cpp11abi + fi echo "#include " > testnewabi.cpp echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp echo "int main() { return static_cast(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp - if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then - ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF + if test -z "`${CXX} ${CXXFLAGS} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/$ecw_license_type/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then + ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/$ECW_ABIDIR/$ECW_ARCH/$ECW_CONF ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA" with_ecw=$with_ecw/$ecw_license_type - AC_MSG_RESULT([found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}.]) + AC_MSG_RESULT([found Intergraph 5.4+ SDK with ${ECW_ABIDIR} in ${ECW_LIBDIR}.]) ECW_54="yes" rm -f testnewabi.* rm -f testnewabi diff --git a/gdal/frmts/ecw/ecwcreatecopy.cpp b/gdal/frmts/ecw/ecwcreatecopy.cpp index b17592720cb..97f8f45f7ff 100644 --- a/gdal/frmts/ecw/ecwcreatecopy.cpp +++ b/gdal/frmts/ecw/ecwcreatecopy.cpp @@ -115,7 +115,7 @@ class GDALECWCompressor final: public CNCSFile { GDALDataset *m_poSrcDS; - VSIIOStream m_OStream; + std::shared_ptr m_OStream; int m_nPercentComplete; int m_bCancelled; @@ -143,7 +143,7 @@ class GDALECWCompressor final: public CNCSFile { /************************************************************************/ GDALECWCompressor::GDALECWCompressor() : - eWorkDT(GDT_Unknown) + m_OStream(std::make_shared()), eWorkDT(GDT_Unknown) { m_poSrcDS = nullptr; m_nPercentComplete = -1; @@ -186,7 +186,7 @@ CPLErr GDALECWCompressor::CloseDown() { Close( true ); - m_OStream.Close(); + m_OStream->Close(); return CE_None; } @@ -1008,7 +1008,7 @@ CPLErr GDALECWCompressor::Initialize( return CE_Failure; } - m_OStream.Access( fpVSIL, TRUE, (BOOLEAN) bSeekable, pszFilename, + m_OStream->Access( fpVSIL, TRUE, (BOOLEAN) bSeekable, pszFilename, 0, -1 ); } else @@ -1114,8 +1114,13 @@ CPLErr GDALECWCompressor::Initialize( oError = GetCNCSError(Open( (char *) pszFilename, false, true )); } } - else - oError = CNCSJP2FileView::Open( &(m_OStream) ); + else { +#if ECWSDK_VERSION>=55 + oError = CNCSJP2FileView::Open(m_OStream); +#else + oError = CNCSJP2FileView::Open(m_OStream.get()); +#endif + } } if( oError.GetErrorNumber() == NCS_SUCCESS ) diff --git a/gdal/frmts/ecw/ecwdataset.cpp b/gdal/frmts/ecw/ecwdataset.cpp index 6ef14bd27d9..c2fbd4f3663 100644 --- a/gdal/frmts/ecw/ecwdataset.cpp +++ b/gdal/frmts/ecw/ecwdataset.cpp @@ -194,11 +194,11 @@ ECWRasterBand::ECWRasterBand( ECWDataset *poDSIn, int nBandIn, int iOverviewIn, CPLDebug("ECW", "Fourth (alpha) band is promoted from 1 bit to 8 bit"); if( (poDSIn->psFileInfo->pBands[nBand-1].nBits % 8) != 0 && !bPromoteTo8Bit ) - SetMetadataItem("NBITS", + GDALPamRasterBand::SetMetadataItem("NBITS", CPLString().Printf("%d",poDSIn->psFileInfo->pBands[nBand-1].nBits), "IMAGE_STRUCTURE" ); - SetDescription(poDSIn->psFileInfo->pBands[nBand-1].szDesc); + GDALPamRasterBand::SetDescription(poDSIn->psFileInfo->pBands[nBand-1].szDesc); } /************************************************************************/ @@ -208,7 +208,7 @@ ECWRasterBand::ECWRasterBand( ECWDataset *poDSIn, int nBandIn, int iOverviewIn, ECWRasterBand::~ECWRasterBand() { - FlushCache(); + GDALRasterBand::FlushCache(); while( !apoOverviews.empty() ) { @@ -266,7 +266,7 @@ CPLErr ECWRasterBand::AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize, GDALDataType eDT, char **papszOptions ) { - int nResFactor = 1 << (iOverview+1); + const int nResFactor = 1 << (iOverview+1); return poGDS->AdviseRead( nXOff * nResFactor, nYOff * nResFactor, @@ -312,13 +312,13 @@ CPLErr ECWRasterBand::GetDefaultHistogram( double *pdfMin, double *pdfMax, NCSBandStats& bandStats = poGDS->pStatistics->BandsStats[nStatsBandIndex]; if ( bandStats.Histogram != nullptr && bandStats.nHistBucketCount > 0 ){ *pnBuckets = bandStats.nHistBucketCount; - *ppanHistogram = (GUIntBig *)VSIMalloc(bandStats.nHistBucketCount *sizeof(GUIntBig)); + *ppanHistogram = static_cast(VSIMalloc(bandStats.nHistBucketCount * sizeof(GUIntBig))); for (size_t i = 0; i < bandStats.nHistBucketCount; i++){ - (*ppanHistogram)[i] = (GUIntBig) bandStats.Histogram[i]; + (*ppanHistogram)[i] = static_cast(bandStats.Histogram[i]); } //JTO: this is not perfect as You can't tell who wrote the histogram !!! //It will offset it unnecessarily for files with hists not modified by GDAL. - double dfHalfBucket = (bandStats.fMaxHist - bandStats.fMinHist) / (2 * (*pnBuckets - 1)); + const double dfHalfBucket = (bandStats.fMaxHist - bandStats.fMinHist) / (2 * (*pnBuckets - 1)); if ( pdfMin != nullptr ){ *pdfMin = bandStats.fMinHist - dfHalfBucket; } @@ -326,11 +326,7 @@ CPLErr ECWRasterBand::GetDefaultHistogram( double *pdfMin, double *pdfMax, *pdfMax = bandStats.fMaxHist + dfHalfBucket; } bHistogramFromFile = true; - }else{ - bHistogramFromFile = false; } - }else{ - bHistogramFromFile = false; } if (!bHistogramFromFile ){ @@ -338,29 +334,21 @@ CPLErr ECWRasterBand::GetDefaultHistogram( double *pdfMin, double *pdfMax, //compute. Save. pamError = GDALPamRasterBand::GetDefaultHistogram(pdfMin, pdfMax, pnBuckets, ppanHistogram, TRUE, f,pProgressData); if (pamError == CE_None){ - CPLErr error2 = SetDefaultHistogram(*pdfMin, *pdfMax, *pnBuckets, *ppanHistogram); + const CPLErr error2 = SetDefaultHistogram(*pdfMin, *pdfMax, *pnBuckets, *ppanHistogram); if (error2 != CE_None){ //Histogram is there but we failed to save it back to file. CPLError (CE_Warning, CPLE_AppDefined, "SetDefaultHistogram failed in ECWRasterBand::GetDefaultHistogram. Histogram might not be saved in .ecw file." ); } return CE_None; - }else{ - //Something went wrong during histogram computation. - return pamError; } + return pamError; } - else - { - // No histogram, no forced computation. - return CE_Warning; - } - } - else - { - // Statistics were already there and were used. - return CE_None; + // No histogram, no forced computation. + return CE_Warning; } + // Statistics were already there and were used. + return CE_None; } /************************************************************************/ @@ -426,7 +414,7 @@ CPLErr ECWRasterBand::SetDefaultHistogram( double dfMin, double dfMax, bucketCounts[i] = pStatistics->BandsStats[i].nHistBucketCount; } bucketCounts[nStatsBandIndex] = nBuckets; - if (nBuckets < (int)pStatistics->BandsStats[nStatsBandIndex].nHistBucketCount){ + if (nBuckets < static_cast(pStatistics->BandsStats[nStatsBandIndex].nHistBucketCount)){ pStatistics->BandsStats[nStatsBandIndex].nHistBucketCount = nBuckets; } error = NCSEcwInitStatistics(&pNewStatistics, nStatsBandCount, bucketCounts); @@ -454,10 +442,10 @@ CPLErr ECWRasterBand::SetDefaultHistogram( double dfMin, double dfMax, //at this point we have allocated statistics structure. double dfHalfBucket = (dfMax - dfMin) / (2 * nBuckets); - pStatistics->BandsStats[nStatsBandIndex].fMinHist = (IEEE4) (dfMin + dfHalfBucket); - pStatistics->BandsStats[nStatsBandIndex].fMaxHist = (IEEE4) (dfMax - dfHalfBucket); + pStatistics->BandsStats[nStatsBandIndex].fMinHist = static_cast(dfMin + dfHalfBucket); + pStatistics->BandsStats[nStatsBandIndex].fMaxHist = static_cast(dfMax - dfHalfBucket); for (int i=0;iBandsStats[nStatsBandIndex].Histogram[i] = (UINT64)panHistogram[i]; + pStatistics->BandsStats[nStatsBandIndex].Histogram[i] = static_cast(panHistogram[i]); } if (hasPAMDefaultHistogram){ @@ -472,7 +460,8 @@ CPLErr ECWRasterBand::SetDefaultHistogram( double dfMin, double dfMax, /* GetBandIndexAndCountForStatistics() */ /************************************************************************/ -void ECWRasterBand::GetBandIndexAndCountForStatistics(int &bandIndex, int &bandCount){ +void ECWRasterBand::GetBandIndexAndCountForStatistics(int &bandIndex, int &bandCount) const +{ bandIndex = nBand-1; bandCount = poGDS->nBands; for (int i=0;inBands;i++){ @@ -500,7 +489,7 @@ double ECWRasterBand::GetMinimum(int* pbSuccess) if ( poGDS->pStatistics != nullptr ) { NCSBandStats& bandStats = poGDS->pStatistics->BandsStats[nStatsBandIndex]; - if ( bandStats.fMinVal == bandStats.fMinVal ) + if (!std::isnan(bandStats.fMinVal)) { if( pbSuccess ) *pbSuccess = TRUE; @@ -527,7 +516,7 @@ double ECWRasterBand::GetMaximum(int* pbSuccess) if ( poGDS->pStatistics != nullptr ) { NCSBandStats& bandStats = poGDS->pStatistics->BandsStats[nStatsBandIndex]; - if ( bandStats.fMaxVal == bandStats.fMaxVal ) + if (!std::isnan(bandStats.fMaxVal)) { if( pbSuccess ) *pbSuccess = TRUE; @@ -549,7 +538,7 @@ CPLErr ECWRasterBand::GetStatistics( int bApproxOK, int bForce, int bForceCoalesced = bForce; // If file version is smaller than 3, there will be no statistics in the file. But if it is version 3 or higher we don't want underlying implementation to compute histogram // so we set bForceCoalesced to FALSE. - if (poGDS->psFileInfo->nFormatVersion >= 3){ + if (poGDS->psFileInfo->nFormatVersion >= 3) { bForceCoalesced = FALSE; } // We check if we have PAM histogram. If we have them we return them. This will allow to override statistics stored in the file. @@ -571,22 +560,22 @@ CPLErr ECWRasterBand::GetStatistics( int bApproxOK, int bForce, { bStatisticsFromFile = true; NCSBandStats& bandStats = poGDS->pStatistics->BandsStats[nStatsBandIndex]; - if ( pdfMin != nullptr && bandStats.fMinVal == bandStats.fMinVal){ + if ( pdfMin != nullptr && !std::isnan(bandStats.fMinVal)) { *pdfMin = bandStats.fMinVal; }else{ bStatisticsFromFile = false; } - if ( pdfMax != nullptr && bandStats.fMaxVal == bandStats.fMaxVal){ + if ( pdfMax != nullptr && !std::isnan(bandStats.fMaxVal)) { *pdfMax = bandStats.fMaxVal; }else{ bStatisticsFromFile = false; } - if ( pdfMean != nullptr && bandStats.fMeanVal == bandStats.fMeanVal){ + if ( pdfMean != nullptr && !std::isnan(bandStats.fMeanVal)) { *pdfMean = bandStats.fMeanVal; }else{ bStatisticsFromFile = false; } - if ( padfStdDev != nullptr && bandStats.fStandardDev == bandStats.fStandardDev){ + if ( padfStdDev != nullptr && !std::isnan(bandStats.fStandardDev)) { *padfStdDev = bandStats.fStandardDev; }else{ bStatisticsFromFile = false; @@ -614,20 +603,18 @@ CPLErr ECWRasterBand::GetStatistics( int bApproxOK, int bForce, *padfStdDev = dfStdDev; } if ( pamError == CE_None){ - CPLErr err = SetStatistics(dfMin,dfMax,dfMean,dfStdDev); + const CPLErr err = SetStatistics(dfMin,dfMax,dfMean,dfStdDev); if (err !=CE_None){ CPLError (CE_Warning, CPLE_AppDefined, "SetStatistics failed in ECWRasterBand::GetDefaultHistogram. Statistics might not be saved in .ecw file." ); } return CE_None; - }else{ - //whatever happened we return. - return pamError; } - }else{ - //no statistics and we are not forced to return. - return CE_Warning; + //whatever happened we return. + return pamError; } + //no statistics and we are not forced to return. + return CE_Warning; } /************************************************************************/ @@ -658,10 +645,10 @@ CPLErr ECWRasterBand::SetStatistics( double dfMin, double dfMax, } } - poGDS->pStatistics->BandsStats[nStatsBandIndex].fMinVal = (IEEE4) dfMin; - poGDS->pStatistics->BandsStats[nStatsBandIndex].fMaxVal = (IEEE4)dfMax; - poGDS->pStatistics->BandsStats[nStatsBandIndex].fMeanVal = (IEEE4)dfMean; - poGDS->pStatistics->BandsStats[nStatsBandIndex].fStandardDev = (IEEE4)dfStdDev; + poGDS->pStatistics->BandsStats[nStatsBandIndex].fMinVal = static_cast(dfMin); + poGDS->pStatistics->BandsStats[nStatsBandIndex].fMaxVal = static_cast(dfMax); + poGDS->pStatistics->BandsStats[nStatsBandIndex].fMeanVal = static_cast(dfMean); + poGDS->pStatistics->BandsStats[nStatsBandIndex].fStandardDev = static_cast(dfStdDev); poGDS->bStatisticsDirty = TRUE; //if we have PAM statistics we need to save them as well. Better option would be to remove them from PAM file but I don't know how to do that without messing in PAM internals. if ( hasPAMStatistics ){ @@ -692,9 +679,9 @@ CPLErr ECWRasterBand::OldIRasterIO( GDALRWFlag eRWFlag, GDALRasterIOExtraArg* psExtraArg ) { - int iBand, bDirect; + int iBand; GByte *pabyWorkBuffer = nullptr; - int nResFactor = 1 << (iOverview+1); + const int nResFactor = 1 << (iOverview+1); nXOff *= nResFactor; nYOff *= nResFactor; @@ -707,12 +694,12 @@ CPLErr ECWRasterBand::OldIRasterIO( GDALRWFlag eRWFlag, int nRet = poGDS->TryWinRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, - (GByte *) pData, nBufXSize, nBufYSize, + static_cast(pData), nBufXSize, nBufYSize, eBufType, 1, &nBand, nPixelSpace, nLineSpace, 0 , psExtraArg); if( nRet == TRUE ) return CE_None; - else if( nRet < 0 ) + if( nRet < 0 ) return CE_Failure; /* -------------------------------------------------------------------- */ @@ -732,12 +719,12 @@ CPLErr ECWRasterBand::OldIRasterIO( GDALRWFlag eRWFlag, /* Can we perform direct loads, or must we load into a working */ /* buffer, and transform? */ /* -------------------------------------------------------------------- */ - int nRawPixelSize = GDALGetDataTypeSize(poGDS->eRasterDataType) / 8; + const int nRawPixelSize = GDALGetDataTypeSize(poGDS->eRasterDataType) / 8; - bDirect = nPixelSpace == 1 && eBufType == GDT_Byte + int bDirect = nPixelSpace == 1 && eBufType == GDT_Byte && nNewXSize == nBufXSize && nNewYSize == nBufYSize; if( !bDirect ) - pabyWorkBuffer = (GByte *) CPLMalloc(nNewXSize * nRawPixelSize); + pabyWorkBuffer = static_cast(CPLMalloc(nNewXSize * nRawPixelSize)); /* -------------------------------------------------------------------- */ /* Establish access at the desired resolution. */ @@ -747,7 +734,7 @@ CPLErr ECWRasterBand::OldIRasterIO( GDALRWFlag eRWFlag, iBand = nBand-1; poGDS->nBandIndexToPromoteTo8Bit = ( bPromoteTo8Bit ) ? 0 : -1; // TODO: Fix writable strings issue. - CNCSError oErr = poGDS->poFileView->SetView( 1, (unsigned int *) (&iBand), + CNCSError oErr = poGDS->poFileView->SetView( 1, reinterpret_cast(&iBand), nXOff, nYOff, nXOff + nXSize - 1, nYOff + nYSize - 1, @@ -765,8 +752,8 @@ CPLErr ECWRasterBand::OldIRasterIO( GDALRWFlag eRWFlag, /* Supersampling is not supported by the ECW API, so we will do */ /* it ourselves. */ /* -------------------------------------------------------------------- */ - double dfSrcYInc = (double)nNewYSize / nBufYSize; - double dfSrcXInc = (double)nNewXSize / nBufXSize; + double dfSrcYInc = static_cast(nNewYSize) / nBufYSize; + double dfSrcXInc = static_cast(nNewXSize) / nBufXSize; int iSrcLine, iDstLine; CPLErr eErr = CE_None; @@ -1017,7 +1004,7 @@ ECWDataset::ECWDataset(int bIsJPEG2000In) ECWDataset::~ECWDataset() { - FlushCache(); + GDALPamDataset::FlushCache(); CleanupWindow(); #if ECWSDK_VERSION>=50 @@ -1070,6 +1057,9 @@ ECWDataset::~ECWDataset() // from the GDAL destructor. if( poFileView != nullptr && !GDALIsInGlobalDestructor() ) { +#if ECWSDK_VERSION >= 55 + delete poFileView; +#else VSIIOStream *poUnderlyingIOStream = (VSIIOStream *)nullptr; if( bUsingCustomStream ) @@ -1083,6 +1073,8 @@ ECWDataset::~ECWDataset() if( --poUnderlyingIOStream->nFileViewCount == 0 ) delete poUnderlyingIOStream; } +#endif + poFileView = nullptr; } /* WriteHeader() must be called after closing the file handle to work */ @@ -2549,11 +2541,21 @@ CNCSJP2FileView *ECWDataset::OpenFileView( const char *pszDatasetName, { CPLDebug( "ECW", "Got mutex." ); } - VSIIOStream *poIOStream = new VSIIOStream(); - poIOStream->Access( fpVSIL, FALSE, TRUE, pszDatasetName, 0, -1 ); - + poFileView = new CNCSJP2FileView(); - oErr = poFileView->Open( poIOStream, bProgressive ); + +#if ECWSDK_VERSION >= 55 + NCS::CString streamName(pszDatasetName); + auto vsiIoStream = NCS::CView::FindSteamByStreamNameFromOpenDatasets(streamName); + if (!vsiIoStream) { + vsiIoStream = std::make_shared(); + std::static_pointer_cast(vsiIoStream)->Access(fpVSIL, FALSE, TRUE, pszDatasetName, 0, -1); + } + oErr = poFileView->Open(vsiIoStream, bProgressive); +#else + auto vsiIoStream = new VSIIOStream(); + vsiIoStream->Access(fpVSIL, FALSE, TRUE, pszDatasetName, 0, -1); + oErr = poFileView->Open(vsiIoStream, bProgressive); // The CNCSJP2FileView (poFileView) object may not use the iostream // (poIOStream) passed to the CNCSJP2FileView::Open() method if an @@ -2575,14 +2577,15 @@ CNCSJP2FileView *ECWDataset::OpenFileView( const char *pszDatasetName, if ( poUnderlyingIOStream ) poUnderlyingIOStream->nFileViewCount++; - if ( poIOStream != poUnderlyingIOStream ) + if ( vsiIoStream != poUnderlyingIOStream ) { - delete poIOStream; + delete vsiIoStream; } else { bUsingCustomStream = TRUE; } +#endif CPLReleaseMutex( hECWDatasetMutex ); diff --git a/gdal/frmts/ecw/gdal_ecw.h b/gdal/frmts/ecw/gdal_ecw.h index 1b479485a33..142a63a21fa 100644 --- a/gdal/frmts/ecw/gdal_ecw.h +++ b/gdal/frmts/ecw/gdal_ecw.h @@ -89,7 +89,10 @@ class JP2UserBox final: public CNCSJP2Box { virtual ~JP2UserBox(); -#if ECWSDK_VERSION >= 40 +#if ECWSDK_VERSION >= 55 + CNCSError Parse(NCS::SDK::CFileBase &JP2File, const NCS::CIOStreamPtr &Stream) override; + CNCSError UnParse(NCS::SDK::CFileBase &JP2File, const NCS::CIOStreamPtr &Stream) override; +#elif ECWSDK_VERSION >= 40 virtual CNCSError Parse(NCS::SDK::CFileBase &JP2File, NCS::CIOStream &Stream) override; virtual CNCSError UnParse(NCS::SDK::CFileBase &JP2File, @@ -116,9 +119,10 @@ class JP2UserBox final: public CNCSJP2Box { /************************************************************************/ class VSIIOStream final: public CNCSJPCIOStream - { - private: +#if ECWSDK_VERSION >= 54 + NCS_DELETE_ALL_COPY_AND_MOVE(VSIIOStream) +#endif char *m_Filename; public: @@ -131,12 +135,13 @@ class VSIIOStream final: public CNCSJPCIOStream int nCOMState; int nCOMLength; - GByte abyCOMType[2]; + GByte abyCOMType[2]{}; /* To fix ‘virtual bool NCS::CIOStream::Read(INT64, void*, UINT32)’ was hidden' with SDK 5 */ using CNCSJPCIOStream::Read; - VSIIOStream() : m_Filename(nullptr){ + VSIIOStream() : m_Filename(nullptr) + { nFileViewCount = 0; startOfJPData = 0; lengthOfJPData = -1; @@ -152,13 +157,13 @@ class VSIIOStream final: public CNCSJPCIOStream abyCOMType[1] = 0; } virtual ~VSIIOStream() { - Close(); + VSIIOStream::Close(); if (m_Filename!=nullptr){ CPLFree(m_Filename); } } - virtual CNCSError Close() override { + CNCSError Close() override { CNCSError oErr = CNCSJPCIOStream::Close(); if( fpVSIL != nullptr ) { @@ -169,18 +174,17 @@ class VSIIOStream final: public CNCSJPCIOStream } #if ECWSDK_VERSION >= 40 - virtual VSIIOStream *Clone() override { + VSIIOStream *Clone() override { CPLDebug( "ECW", "VSIIOStream::Clone()" ); VSILFILE *fpNewVSIL = VSIFOpenL( m_Filename, "rb" ); if (fpNewVSIL == nullptr) { return nullptr; - }else - { - VSIIOStream *pDst = new VSIIOStream(); - pDst->Access(fpNewVSIL, bWritable, bSeekable, m_Filename, startOfJPData, lengthOfJPData); - return pDst; } + + VSIIOStream *pDst = new VSIIOStream(); + pDst->Access(fpNewVSIL, bWritable, bSeekable, m_Filename, startOfJPData, lengthOfJPData); + return pDst; } #endif /* ECWSDK_VERSION >= 4 */ @@ -199,9 +203,10 @@ class VSIIOStream final: public CNCSJPCIOStream // if it does not have a path to a real directory, we will // substitute something. CPLString osFilenameUsed = pszFilename; +#if ECWSDK_VERSION < 55 CPLString osPath = CPLGetPath( pszFilename ); struct stat sStatBuf; - if( osPath != "" && stat( osPath, &sStatBuf ) != 0 ) + if( !osPath.empty() && stat( osPath, &sStatBuf ) != 0 ) { osFilenameUsed = CPLGenerateTempFilename( nullptr ); // try to preserve the extension. @@ -212,6 +217,8 @@ class VSIIOStream final: public CNCSJPCIOStream } CPLDebug( "ECW", "Using filename '%s' for temporary directory determination purposes.", osFilenameUsed.c_str() ); } +#endif + #ifdef WIN32 if( CSLTestBoolean( CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES" ) ) ) { @@ -662,7 +669,7 @@ class ECWRasterBand final: public GDALPamRasterBand int nBufXSize, int nBufYSize, GDALDataType eDT, char **papszOptions ) override; #if ECWSDK_VERSION >= 50 - void GetBandIndexAndCountForStatistics(int &bandIndex, int &bandCount); + void GetBandIndexAndCountForStatistics(int &bandIndex, int &bandCount) const; virtual CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax, int *pnBuckets, GUIntBig ** ppanHistogram, int bForce, diff --git a/gdal/frmts/ecw/jp2userbox.cpp b/gdal/frmts/ecw/jp2userbox.cpp index 2829835a5af..367cc696cfb 100644 --- a/gdal/frmts/ecw/jp2userbox.cpp +++ b/gdal/frmts/ecw/jp2userbox.cpp @@ -72,7 +72,7 @@ void JP2UserBox::SetData( int nLengthIn, const unsigned char *pabyDataIn ) CPLFree( pabyData ); nDataLength = nLengthIn; - pabyData = (unsigned char *) CPLMalloc(nDataLength); + pabyData = static_cast(CPLMalloc(nDataLength)); memcpy( pabyData, pabyDataIn, nDataLength ); m_bValid = true; @@ -94,8 +94,10 @@ void JP2UserBox::UpdateXLBox() /* */ /* Parse box, and data contents from file into memory. */ /************************************************************************/ - -#if ECWSDK_VERSION >= 40 +#if ECWSDK_VERSION >= 55 +CNCSError JP2UserBox::Parse(CPL_UNUSED NCS::SDK::CFileBase &JP2File, + CPL_UNUSED const NCS::CIOStreamPtr &Stream) +#elif ECWSDK_VERSION >= 40 CNCSError JP2UserBox::Parse( CPL_UNUSED NCS::SDK::CFileBase &JP2File, CPL_UNUSED NCS::CIOStream &Stream ) #else @@ -113,8 +115,10 @@ CNCSError JP2UserBox::Parse( CPL_UNUSED class CNCSJP2File &JP2File, /* */ /* Write box meta information, and data to file. */ /************************************************************************/ - -#if ECWSDK_VERSION >= 40 +#if ECWSDK_VERSION >= 55 +CNCSError JP2UserBox::UnParse(NCS::SDK::CFileBase &JP2File, + const NCS::CIOStreamPtr &Stream) +#elif ECWSDK_VERSION >= 40 CNCSError JP2UserBox::UnParse( NCS::SDK::CFileBase &JP2File, NCS::CIOStream &Stream ) #else @@ -136,9 +140,12 @@ CNCSError JP2UserBox::UnParse( class CNCSJP2File &JP2File, #else Error = CNCSSDKBox::UnParse(JP2File, Stream); #endif -// NCSJP2_CHECKIO_BEGIN(Error, Stream); + +#if ECWSDK_VERSION >= 55 + Stream->Write(pabyData, nDataLength); +#else Stream.Write(pabyData, nDataLength); -// NCSJP2_CHECKIO_END(); +#endif return Error; } diff --git a/gdal/nmake.opt b/gdal/nmake.opt index 17f252e44b5..910acb17987 100644 --- a/gdal/nmake.opt +++ b/gdal/nmake.opt @@ -342,13 +342,34 @@ JPEG12_SUPPORTED = 1 # NCSEcw4.lib, and add -DHAVE_COMPRESS to ECWFLAGS. The ECWDIR setting will # also need some adjustment. -# Uncomment the following and update to enable ECW read support with the 5.0 SDK -#ECWDIR = "c:\Intergraph\ecwsdk5" -#ECWFLAGS = -DECWSDK_VERSION=50 \ -# -I$(ECWDIR)\include \ -# -I$(ECWDIR)\include/NCSECW/api -I$(ECWDIR)\include/NCSECW/jp2 \ -# -I$(ECWDIR)\include/NCSECW/ecw -#ECWLIB = $(ECWDIR)\lib\vc90\win32\NCSEcw.lib +# Uncomment the following and update to enable ECW read support with the 5.0+ SDK +#!IF $(MSVC_VER) < 1910 +#ECW_PLATFORM_TOOLSET_DIR = vc140 +#!ELSE +#ECW_PLATFORM_TOOLSET_DIR = vc141 +#!ENDIF + +#!IF "$(DEBUG)" == "1" +#ECW_LIB_DEBUG_SUFFIX = d +#!ENDIF + +#!IF "$(WIN64)" == "1" +#ECW_PLATFORM_DIR = x64 +#!ELSE +#ECW_PLATFORM_DIR = Win32 +#!ENDIF + +#ECWDIR = "C:/Hexagon/ERDAS ECW JPEG 2000 SDK 5.4.0/Desktop Read-Only" +#ECWDIR = "C:/Hexagon/ERDAS ECW JPEG 2000 SDK 5.5.0/Desktop Read-Only" +#ECW_MAJOR_MINOR_VERSION = 55 + +#ECW_INCLUDES = -I$(ECWDIR)/include \ +# -I$(ECWDIR)/include/NCSEcw/API -I$(ECWDIR)/include/NCSEcw/JP2 \ +# -I$(ECWDIR)/include/NCSEcw/ECW + +#ECW_ENABLE_COMPRESSION = -DHAVE_COMPRESS +#ECWFLAGS = -DECWSDK_VERSION=$(ECW_MAJOR_MINOR_VERSION) $(ECW_ENABLE_COMPRESSION) $(ECW_INCLUDES) +#ECWLIB = $(ECWDIR)\lib\$(ECW_PLATFORM_TOOLSET_DIR)\$(ECW_PLATFORM_DIR)\NCSEcw$(ECW_LIB_LINK_SUFFIX).lib # To build ECW support as a plugin uncomment the following, and make sure # to do "nmake /f makefile.vc plugin" in gdal/frmts/ecw and copy the two