From b938ad014e3a13dc9c84dd2712526e0a898bd5a16684c20bd8a7d490a9fd93e2 Mon Sep 17 00:00:00 2001 From: Martin Pluskal Date: Sat, 11 Apr 2020 06:22:15 +0000 Subject: [PATCH] Accepting request 792754 from home:Guillaume_G:branches:home:Le_Docteur - Rework ECW5 SDK handling - Fix build with ECW SDK 5.5 with upstream backports: * gdal-ecwjp2-sdk-5.5.patch * gdal-ecwjp2-sdk-5.5_dep1.patch OBS-URL: https://build.opensuse.org/request/show/792754 OBS-URL: https://build.opensuse.org/package/show/Application:Geo/gdal?expand=0&rev=110 --- gdal-ecwjp2-sdk-5.5.patch | 775 +++++++++++++++++++++++++++++++++ gdal-ecwjp2-sdk-5.5_dep1.patch | 52 +++ gdal.changes | 8 + gdal.spec | 22 +- 4 files changed, 846 insertions(+), 11 deletions(-) create mode 100644 gdal-ecwjp2-sdk-5.5.patch create mode 100644 gdal-ecwjp2-sdk-5.5_dep1.patch diff --git a/gdal-ecwjp2-sdk-5.5.patch b/gdal-ecwjp2-sdk-5.5.patch new file mode 100644 index 0000000..5579f12 --- /dev/null +++ b/gdal-ecwjp2-sdk-5.5.patch @@ -0,0 +1,775 @@ +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 diff --git a/gdal-ecwjp2-sdk-5.5_dep1.patch b/gdal-ecwjp2-sdk-5.5_dep1.patch new file mode 100644 index 0000000..d08d77f --- /dev/null +++ b/gdal-ecwjp2-sdk-5.5_dep1.patch @@ -0,0 +1,52 @@ +diff --git a/gdal/frmts/ecw/gdal_ecw.h b/gdal/frmts/ecw/gdal_ecw.h +index e1b6772934a..1b479485a33 100644 +--- a/gdal/frmts/ecw/gdal_ecw.h ++++ b/gdal/frmts/ecw/gdal_ecw.h +@@ -76,9 +76,9 @@ void ECWReportError(CNCSError& oErr, const char* pszMsg = ""); + /************************************************************************/ + #ifdef HAVE_COMPRESS + #if ECWSDK_VERSION>=50 +-class JP2UserBox : public CNCSSDKBox { ++class JP2UserBox final: public CNCSSDKBox { + #else +-class JP2UserBox : public CNCSJP2Box { ++class JP2UserBox final: public CNCSJP2Box { + #endif + private: + int nDataLength; +@@ -115,7 +115,7 @@ class JP2UserBox : public CNCSJP2Box { + /* ==================================================================== */ + /************************************************************************/ + +-class VSIIOStream : public CNCSJPCIOStream ++class VSIIOStream final: public CNCSJPCIOStream + + { + private: +@@ -395,7 +395,7 @@ class ECWDataset; + + #if ECWSDK_VERSION >= 40 + +-class ECWAsyncReader : public GDALAsyncReader ++class ECWAsyncReader final: public GDALAsyncReader + { + private: + CNCSJP2FileView *poFileView = nullptr; +@@ -444,7 +444,7 @@ typedef struct + GByte* pabyData; + } ECWCachedMultiBandIO; + +-class CPL_DLL ECWDataset : public GDALJP2AbstractDataset ++class CPL_DLL ECWDataset final: public GDALJP2AbstractDataset + { + friend class ECWRasterBand; + friend class ECWAsyncReader; +@@ -611,7 +611,7 @@ class CPL_DLL ECWDataset : public GDALJP2AbstractDataset + /* ==================================================================== */ + /************************************************************************/ + +-class ECWRasterBand : public GDALPamRasterBand ++class ECWRasterBand final: public GDALPamRasterBand + { + friend class ECWDataset; + diff --git a/gdal.changes b/gdal.changes index 163e5d6..8b4120a 100644 --- a/gdal.changes +++ b/gdal.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Apr 9 10:22:54 UTC 2020 - Guillaume GARDET + +- Rework ECW5 SDK handling +- Fix build with ECW SDK 5.5 with upstream backports: + * gdal-ecwjp2-sdk-5.5.patch + * gdal-ecwjp2-sdk-5.5_dep1.patch + ------------------------------------------------------------------- Sat Feb 1 08:52:49 UTC 2020 - Bruno Friedmann diff --git a/gdal.spec b/gdal.spec index 79a1058..983af17 100644 --- a/gdal.spec +++ b/gdal.spec @@ -36,6 +36,9 @@ Source1: http://download.osgeo.org/%{name}/%{version}/%{sourcename}-%{ver Patch0: gdal-perl.patch # Fix occasional parallel build failure Patch1: GDALmake.opt.in.patch +# PATCH-FIX-UPSTREAM - https://github.com/OSGeo/gdal/commit/e5cb5406ea9090b2f17cffeeb7ba5fb49e7158f2 + dep commit +Patch2: gdal-ecwjp2-sdk-5.5_dep1.patch +Patch3: gdal-ecwjp2-sdk-5.5.patch BuildRequires: KEALib-devel BuildRequires: autoconf BuildRequires: automake @@ -156,7 +159,10 @@ The GDAL python modules provide support to handle multiple GIS file formats. %prep %setup -q -n %{sourcename}-%{version} -%autopatch -p1 +%patch0 -p1 +%patch1 -p1 +%patch2 -p2 +%patch3 -p2 # Set the right (build) libproj.so version, use the upper found version. PROJSOVER=$(ls -1 %{_libdir}/libproj.so.?? | tail -n1 | awk -F '.' '{print $3}') @@ -173,20 +179,14 @@ done find . -type f -name "style_ogr_brush.png" -exec chmod 0644 {} \; find . -type f -name "style_ogr_sym.png" -exec chmod 0644 {} \; -#Fix wrong /usr/bin/env phyton +# Fix wrong /usr/bin/env phyton #Create the move to python3 find . -iname "*.py" -exec sed -i 's,^#!%{_bindir}/env python$,#!%{_bindir}/python3,' {} \; %if %{with ecw5_support} # gdal configure script looks for a given layout, so reproduce what is expected. -%if 0%{?suse_version} >= 1500 -%define ecw_abi_conf newabi -%else -%define ecw_abi_conf "" -%endif -mkdir -p ../ECW/Desktop_Read-Only/lib/%{ecw_abi_conf}/x64/release/ -mkdir -p ../ECW/Desktop_Read-Only/include -cp %{_libdir}/libNCSEcw* ../ECW/Desktop_Read-Only/lib/%{ecw_abi_conf}/x64/release/ -cp -r %{_includedir}/{ECW*,NCS*} ../ECW/Desktop_Read-Only/include/ +mkdir -p ../ECW/Desktop_Read-Only/lib/x64/ +ln -s %{_libdir} ../ECW/Desktop_Read-Only/lib/x64/release +ln -s %{_includedir} ../ECW/Desktop_Read-Only/include %endif %build