1 /******************************************************************************
2  * $Id: gdal_ecw.h 0d8c4003fd3291dd14fad164eef25599b684a0ae 2021-03-22 15:02:53 +0100 Even Rouault $
3  *
4  * Project:  GDAL
5  * Purpose:  ECW (ERDAS Wavelet Compression Format) Driver Definitions
6  * Author:   Frank Warmerdam, warmerdam@pobox.com
7  *
8  ******************************************************************************
9  * Copyright (c) 2001-2011, Frank Warmerdam <warmerdam@pobox.com>
10  * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #ifndef GDAL_ECW_H_INCLUDED
32 #define GDAL_ECW_H_INCLUDED
33 
34 #include "gdaljp2abstractdataset.h"
35 #include "gdal_frmts.h"
36 #include "cpl_string.h"
37 #include "cpl_conv.h"
38 #include "cpl_multiproc.h"
39 #include "cpl_vsi.h"
40 
41 #undef NOISY_DEBUG
42 
43 #ifdef FRMT_ecw
44 
45 #include "ecwsdk_headers.h"
46 
47 #if ECWSDK_VERSION >= 55
48 #include "NCSIOStreamOptions.h"
49 #endif
50 
51 
52 void ECWInitialize( void );
53 GDALDataset* ECWDatasetOpenJPEG2000(GDALOpenInfo* poOpenInfo);
54 const char* ECWGetColorInterpretationName(GDALColorInterp eColorInterpretation, int nBandNumber);
55 GDALColorInterp ECWGetColorInterpretationByName(const char *pszName);
56 const char* ECWGetColorSpaceName(NCSFileColorSpace colorSpace);
57 #ifdef HAVE_COMPRESS
58 GDALDataset *
59 ECWCreateCopyECW( const char * pszFilename, GDALDataset *poSrcDS,
60                  int bStrict, char ** papszOptions,
61                  GDALProgressFunc pfnProgress, void * pProgressData );
62 GDALDataset *
63 ECWCreateCopyJPEG2000( const char * pszFilename, GDALDataset *poSrcDS,
64                  int bStrict, char ** papszOptions,
65                  GDALProgressFunc pfnProgress, void * pProgressData );
66 
67 GDALDataset *
68 ECWCreateECW( const char * pszFilename, int nXSize, int nYSize, int nBands,
69               GDALDataType eType, char **papszOptions );
70 GDALDataset *
71 ECWCreateJPEG2000(const char *pszFilename, int nXSize, int nYSize, int nBands,
72                   GDALDataType eType, char **papszOptions );
73 #endif
74 
75 void ECWReportError(CNCSError& oErr, const char* pszMsg = "");
76 
77 /************************************************************************/
78 /* ==================================================================== */
79 /*                             JP2Userbox                               */
80 /* ==================================================================== */
81 /************************************************************************/
82 #ifdef HAVE_COMPRESS
83 #if ECWSDK_VERSION>=50
84 class JP2UserBox final: public CNCSSDKBox {
85 #else
86 class JP2UserBox final: public CNCSJP2Box {
87 #endif
88 private:
89     int           nDataLength;
90     unsigned char *pabyData;
91 
92 public:
93     JP2UserBox();
94 
95     virtual ~JP2UserBox();
96 
97 #if ECWSDK_VERSION >= 55
98     CNCSError Parse(NCS::SDK::CFileBase &JP2File, const NCS::CIOStreamPtr &Stream) override;
99     CNCSError UnParse(NCS::SDK::CFileBase &JP2File, const NCS::CIOStreamPtr &Stream) override;
100 #elif ECWSDK_VERSION >= 40
101     virtual CNCSError Parse(NCS::SDK::CFileBase &JP2File,
102                              NCS::CIOStream &Stream) override;
103     virtual CNCSError UnParse(NCS::SDK::CFileBase &JP2File,
104                                 NCS::CIOStream &Stream) override;
105 #else
106     virtual CNCSError Parse(class CNCSJP2File &JP2File,
107                             CNCSJPCIOStream &Stream) override;
108     virtual CNCSError UnParse(class CNCSJP2File &JP2File,
109                               CNCSJPCIOStream &Stream) override;
110 #endif
111     virtual void UpdateXLBox() override;
112 
113     void    SetData( int nDataLength, const unsigned char *pabyDataIn );
114 
GetDataLength()115     int     GetDataLength() { return nDataLength; }
GetData()116     unsigned char *GetData() { return pabyData; }
117 };
118 #endif /* def HAVE_COMPRESS */
119 
120 /************************************************************************/
121 /* ==================================================================== */
122 /*                             VSIIOStream                              */
123 /* ==================================================================== */
124 /************************************************************************/
125 
126 class VSIIOStream final: public CNCSJPCIOStream
127 {
128     VSIIOStream(const VSIIOStream &) = delete;
129     VSIIOStream& operator= (const VSIIOStream&) = delete;
130     VSIIOStream(VSIIOStream &&) = delete;
131     VSIIOStream& operator= (VSIIOStream &&) = delete;
132 
133     char     *m_Filename;
134   public:
135 
136     INT64    startOfJPData;
137     INT64    lengthOfJPData;
138     VSILFILE    *fpVSIL;
139     BOOLEAN      bWritable;
140     BOOLEAN      bSeekable;
141     int      nFileViewCount;
142 
143     int      nCOMState;
144     int      nCOMLength;
145     GByte    abyCOMType[2]{};
146 
147     /* To fix ‘virtual bool NCS::CIOStream::Read(INT64, void*, UINT32)’ was hidden' with SDK 5 */
148     using CNCSJPCIOStream::Read;
149 
VSIIOStream()150     VSIIOStream() : m_Filename(nullptr)
151     {
152         nFileViewCount = 0;
153         startOfJPData = 0;
154         lengthOfJPData = -1;
155         fpVSIL = nullptr;
156         bWritable = false;
157         bSeekable = false;
158         if( CSLTestBoolean(CPLGetConfigOption("GDAL_ECW_WRITE_COMPRESSION_SOFTWARE", "YES")) )
159             nCOMState = -1;
160         else
161             nCOMState = 0;
162         nCOMLength = 0;
163         abyCOMType[0] = 0;
164         abyCOMType[1] = 0;
165     }
~VSIIOStream()166     virtual ~VSIIOStream() {
167         VSIIOStream::Close();
168         if (m_Filename!=nullptr){
169             CPLFree(m_Filename);
170         }
171     }
172 
Close()173     CNCSError Close() override {
174         CNCSError oErr = CNCSJPCIOStream::Close();
175         if( fpVSIL != nullptr )
176         {
177             VSIFCloseL( fpVSIL );
178             fpVSIL = nullptr;
179         }
180         return oErr;
181     }
182 
183 #if ECWSDK_VERSION >= 40
Clone()184     VSIIOStream *Clone() override {
185         CPLDebug( "ECW", "VSIIOStream::Clone()" );
186         VSILFILE *fpNewVSIL = VSIFOpenL( m_Filename, "rb" );
187         if (fpNewVSIL == nullptr)
188         {
189             return nullptr;
190         }
191 
192         VSIIOStream *pDst = new VSIIOStream();
193         pDst->Access(fpNewVSIL, bWritable, bSeekable, m_Filename, startOfJPData, lengthOfJPData);
194         return pDst;
195     }
196 #endif /* ECWSDK_VERSION >= 4 */
197 
198     CNCSError Access( VSILFILE *fpVSILIn, BOOLEAN bWrite, BOOLEAN bSeekableIn,
199                               const char *pszFilename,
200                               INT64 start, INT64 size = -1) {
201 
202         fpVSIL = fpVSILIn;
203         startOfJPData = start;
204         lengthOfJPData = size;
205         bWritable = bWrite;
206         bSeekable = bSeekableIn;
207         VSIFSeekL(fpVSIL, startOfJPData, SEEK_SET);
208         m_Filename = CPLStrdup(pszFilename);
209 
210 #if ECWSDK_VERSION >= 55
211         const std::string vsiStreamPrefix("STREAM=/vsi");
212         const std::string vsiPrefix("/vsi");
213         m_StreamOptions->SetIsRemoteStream(
214             std::string(m_Filename).compare(0, vsiPrefix.length(), vsiPrefix) == 0 ||
215             std::string(m_Filename).compare(0, vsiStreamPrefix.length(), vsiStreamPrefix) == 0
216         );
217 #endif
218         // the filename is used to establish where to put temporary files.
219         // if it does not have a path to a real directory, we will
220         // substitute something.
221         CPLString osFilenameUsed = pszFilename;
222 
223 #if ECWSDK_VERSION < 55
224         CPLString osPath = CPLGetPath( pszFilename );
225         struct stat sStatBuf;
226         if( !osPath.empty() && stat( osPath, &sStatBuf ) != 0 )
227         {
228             osFilenameUsed = CPLGenerateTempFilename( nullptr );
229             // try to preserve the extension.
230             if( strlen(CPLGetExtension(pszFilename)) > 0 )
231             {
232                 osFilenameUsed += ".";
233                 osFilenameUsed += CPLGetExtension(pszFilename);
234             }
235             CPLDebug( "ECW", "Using filename '%s' for temporary directory determination purposes.", osFilenameUsed.c_str() );
236         }
237 #endif
238 
239 #ifdef WIN32
240         if( CSLTestBoolean( CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES" ) ) )
241         {
242             wchar_t       *pwszFilename = CPLRecodeToWChar( osFilenameUsed.c_str(), CPL_ENC_UTF8, CPL_ENC_UCS2 );
243             CNCSError oError;
244             oError = CNCSJPCIOStream::Open( pwszFilename, (bool) bWrite );
245             CPLFree( pwszFilename );
246             return oError;
247         }
248         else
249 #endif
250         {
251             return(CNCSJPCIOStream::Open((char *)osFilenameUsed.c_str(),
252                                         (bool) bWrite));
253         }
254     }
255 
Seek()256     virtual bool NCS_FASTCALL Seek() override {
257         return bSeekable;
258     }
259 
260     virtual bool NCS_FASTCALL Seek(INT64 offset, Origin origin = CURRENT) override {
261 #ifdef DEBUG_VERBOSE
262         CPLDebug( "ECW", "VSIIOStream::Seek(" CPL_FRMT_GIB ",%d)",
263                   static_cast<GIntBig>(offset), (int) origin );
264 #endif
265         bool success = false;
266         switch(origin) {
267             case START:
268               success = (0 == VSIFSeekL(fpVSIL, offset+startOfJPData, SEEK_SET));
269               break;
270 
271             case CURRENT:
272               success = (0 == VSIFSeekL(fpVSIL, offset, SEEK_CUR));
273               break;
274 
275             case END:
276               success = (0 == VSIFSeekL(fpVSIL, offset, SEEK_END));
277               break;
278         }
279         if( !success )
280             CPLDebug( "ECW", "VSIIOStream::Seek(%d,%d) failed.",
281                       (int) offset, (int) origin );
282         return(success);
283     }
284 
Tell()285     virtual INT64 NCS_FASTCALL Tell() override {
286         return VSIFTellL( fpVSIL ) - startOfJPData;
287     }
288 
Size()289     virtual INT64 NCS_FASTCALL Size() override {
290         if( lengthOfJPData != -1 )
291             return lengthOfJPData;
292         else
293         {
294             INT64 curPos = Tell(), size;
295 
296             Seek( 0, END );
297             size = Tell();
298             Seek( curPos, START );
299 #ifdef DEBUG_VERBOSE
300             CPLDebug( "ECW", "VSIIOStream::Size()=" CPL_FRMT_GIB, static_cast<GIntBig>(size) );
301 #endif
302             return size;
303         }
304     }
305 
306 #if ECWSDK_VERSION >= 40
307     /* New, and needed, in ECW SDK 4 */
Read(INT64 offset,void * buffer,UINT32 count)308     virtual bool Read(INT64 offset, void* buffer, UINT32 count) override
309     {
310 #ifdef DEBUG_VERBOSE
311       CPLDebug( "ECW", "VSIIOStream::Read(" CPL_FRMT_GIB ",%u)", static_cast<GIntBig>(offset), count );
312 #endif
313       /* SDK 4.3 doc says it is not supposed to update the file pointer. */
314       /* Later versions have no comment... */
315       INT64 curPos = Tell();
316       Seek( offset, START );
317       bool ret = Read(buffer, count);
318       Seek( curPos, START );
319       return ret;
320     }
321 #endif
322 
Read(void * buffer,UINT32 count)323     virtual bool NCS_FASTCALL Read(void* buffer, UINT32 count) override {
324 #ifdef DEBUG_VERBOSE
325         CPLDebug( "ECW", "VSIIOStream::Read(%u)", count );
326 #endif
327         if( count == 0 )
328             return true;
329 
330 //        return(1 == VSIFReadL( buffer, count, 1, fpVSIL ) );
331 
332         // The following is a hack
333         if( VSIFReadL( buffer, count, 1, fpVSIL ) != 1 )
334         {
335             CPLDebug( "VSIIOSTREAM",
336                       "Read(%d) failed @ " CPL_FRMT_GIB ", ignoring failure.",
337                       count, (VSIFTellL( fpVSIL ) - startOfJPData) );
338         }
339 
340         return true;
341     }
342 
Write(void * buffer,UINT32 count)343     virtual bool NCS_FASTCALL Write(void* buffer, UINT32 count) override {
344         if( count == 0 )
345             return true;
346 
347         GByte* paby = (GByte*) buffer;
348         if( nCOMState == 0 )
349         {
350             if( count == 2 && paby[0] == 0xff && paby[1] == 0x64 )
351             {
352                 nCOMState ++;
353                 return true;
354             }
355         }
356         else if( nCOMState == 1 )
357         {
358             if( count == 2 )
359             {
360                 nCOMLength = (paby[0] << 8) | paby[1];
361                 nCOMState ++;
362                 return true;
363             }
364             else
365             {
366                 GByte prevBuffer[] = { 0xff, 0x64 };
367                 VSIFWriteL(prevBuffer, 2, 1, fpVSIL);
368                 nCOMState = 0;
369             }
370         }
371         else if( nCOMState == 2 )
372         {
373             if( count == 2 )
374             {
375                 abyCOMType[0] = paby[0];
376                 abyCOMType[1] = paby[1];
377                 nCOMState ++;
378                 return true;
379             }
380             else
381             {
382                 GByte prevBuffer[] =
383                   { (GByte)(nCOMLength >> 8), (GByte) (nCOMLength & 0xff) };
384                 VSIFWriteL(prevBuffer, 2, 1, fpVSIL);
385                 nCOMState = 0;
386             }
387         }
388         else if( nCOMState == 3 )
389         {
390             if( count == (UINT32)nCOMLength - 4 )
391             {
392                 nCOMState = 0;
393                 return true;
394             }
395             else
396             {
397                 VSIFWriteL(abyCOMType, 2, 1, fpVSIL);
398                 nCOMState = 0;
399             }
400         }
401 
402         if( 1 != VSIFWriteL(buffer, count, 1, fpVSIL) )
403         {
404             CPLDebug( "ECW", "VSIIOStream::Write(%d) failed.",
405                       (int) count );
406             return false;
407         }
408         else
409             return true;
410     }
411 };
412 
413 /************************************************************************/
414 /* ==================================================================== */
415 /*                            ECWAsyncReader                            */
416 /* ==================================================================== */
417 /************************************************************************/
418 class ECWDataset;
419 
420 #if ECWSDK_VERSION >= 40
421 
422 class ECWAsyncReader final: public GDALAsyncReader
423 {
424 private:
425     CNCSJP2FileView *poFileView = nullptr;
426     CPLMutex        *hMutex = nullptr;
427     int              bUsingCustomStream = false;
428 
429     int              bUpdateReady = false;
430     int              bComplete = false;
431 
432     static NCSEcwReadStatus RefreshCB( NCSFileView * );
433     NCSEcwReadStatus ReadToBuffer();
434 
435 public:
436     ECWAsyncReader();
437     virtual ~ECWAsyncReader();
438     virtual GDALAsyncStatusType GetNextUpdatedRegion(double dfTimeout,
439                                                      int* pnXBufOff,
440                                                      int* pnYBufOff,
441                                                      int* pnXBufSize,
442                                                      int* pnYBufSize) override;
443 
444     friend class ECWDataset;
445 };
446 #endif /* ECWSDK_VERSION >= 40 */
447 
448 /************************************************************************/
449 /* ==================================================================== */
450 /*                              ECWDataset                              */
451 /* ==================================================================== */
452 /************************************************************************/
453 
454 class ECWRasterBand;
455 
456 typedef struct
457 {
458     int bEnabled;
459     int nBandsTried;
460 
461     int nXOff;
462     int nYOff;
463     int nXSize;
464     int nYSize;
465     int nBufXSize;
466     int nBufYSize;
467     GDALDataType eBufType;
468     GByte* pabyData;
469 } ECWCachedMultiBandIO;
470 
471 class CPL_DLL ECWDataset final: public GDALJP2AbstractDataset
472 {
473     friend class ECWRasterBand;
474     friend class ECWAsyncReader;
475 
476     int         bIsJPEG2000;
477 
478     CNCSJP2FileView *poFileView;
479     NCSFileViewFileInfoEx *psFileInfo;
480 
481     GDALDataType eRasterDataType;
482     NCSEcwCellType eNCSRequestDataType;
483 
484     int         bUsingCustomStream;
485 
486     // Current view window.
487     int         bWinActive;
488     int         nWinXOff, nWinYOff, nWinXSize, nWinYSize;
489     int         nWinBufXSize, nWinBufYSize;
490     int         nWinBandCount;
491     int         *panWinBandList;
492     int         nWinBufLoaded;
493     void        **papCurLineBuf;
494 
495     // Deferred advise read parameters
496     int         m_nAdviseReadXOff;
497     int         m_nAdviseReadYOff;
498     int         m_nAdviseReadXSize;
499     int         m_nAdviseReadYSize;
500     int         m_nAdviseReadBufXSize;
501     int         m_nAdviseReadBufYSize;
502     int         m_nAdviseReadBandCount;
503     int        *m_panAdviseReadBandList;
504 
505     char        **papszGMLMetadata;
506 
507     ECWCachedMultiBandIO sCachedMultiBandIO;
508 
509     void        ECW2WKTProjection();
510 
511     void        CleanupWindow();
512     CPLErr      RunDeferredAdviseRead();
513     int         TryWinRasterIO( GDALRWFlag, int, int, int, int,
514                                 GByte *, int, int, GDALDataType,
515                                 int, int *,
516                                 GSpacing nPixelSpace, GSpacing nLineSpace,
517                                 GSpacing nBandSpace,
518                                 GDALRasterIOExtraArg* psExtraArg );
519     CPLErr      LoadNextLine();
520 
521 #if ECWSDK_VERSION>=50
522 
523     NCSFileStatistics* pStatistics;
524     int bStatisticsDirty;
525     int bStatisticsInitialized;
526     NCS::CError StatisticsEnsureInitialized();
527     NCS::CError StatisticsWrite();
528     void CleanupStatistics();
529     void ReadFileMetaDataFromFile();
530 
531     int bFileMetaDataDirty;
532     void WriteFileMetaData(NCSFileMetaData* pFileMetaDataCopy);
533 
534 #endif
535 
536     static CNCSJP2FileView    *OpenFileView( const char *pszDatasetName,
537                                              bool bProgressive,
538                                              int &bUsingCustomStream,
539                                              bool bWrite=false);
540 
541     int         bHdrDirty;
542     CPLString   m_osDatumCode;
543     CPLString   m_osProjCode;
544     CPLString   m_osUnitsCode;
545     int         bGeoTransformChanged;
546     int         bProjectionChanged;
547     int         bProjCodeChanged;
548     int         bDatumCodeChanged;
549     int         bUnitsCodeChanged;
550     void        WriteHeader();
551 
552     int         bUseOldBandRasterIOImplementation;
553 
554     int         bPreventCopyingSomeMetadata;
555 
556     int         nBandIndexToPromoteTo8Bit;
557 
558     CPLStringList oECWMetadataList;
559     CPLErr ReadBands(void * pData, int nBufXSize, int nBufYSize,
560                     GDALDataType eBufType,
561                     int nBandCount,
562                     GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace,
563                     GDALRasterIOExtraArg* psExtraArg);
564     CPLErr ReadBandsDirectly(void * pData, int nBufXSize, int nBufYSize,
565                     GDALDataType eBufType,
566                     int nBandCount,
567                     GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace,
568                     GDALRasterIOExtraArg* psExtraArg);
569   public:
570         ECWDataset(int bIsJPEG2000);
571         ~ECWDataset();
572 
573     static GDALDataset *Open( GDALOpenInfo *, int bIsJPEG2000 );
574     static int          IdentifyJPEG2000( GDALOpenInfo * poOpenInfo );
575     static GDALDataset *OpenJPEG2000( GDALOpenInfo * );
576     static int          IdentifyECW( GDALOpenInfo * poOpenInfo );
577     static GDALDataset *OpenECW( GDALOpenInfo * );
578 
SetPreventCopyingSomeMetadata(int b)579     void        SetPreventCopyingSomeMetadata(int b) { bPreventCopyingSomeMetadata = b; }
580 
581     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
582                               void *, int, int, GDALDataType,
583                               int, int *,
584                               GSpacing nPixelSpace, GSpacing nLineSpace,
585                               GSpacing nBandSpace,
586                               GDALRasterIOExtraArg* psExtraArg) override;
587 
588     virtual char      **GetMetadataDomainList() override;
589     virtual const char *GetMetadataItem( const char * pszName,
590                                      const char * pszDomain = "" ) override;
591     virtual char      **GetMetadata( const char * pszDomain = "" ) override;
592 
593     virtual CPLErr SetGeoTransform( double * padfGeoTransform ) override;
594     virtual CPLErr _SetProjection( const char* pszProjection ) override;
SetSpatialRef(const OGRSpatialReference * poSRS)595     CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override {
596         return OldSetProjectionFromSetSpatialRef(poSRS);
597     }
598 
599     virtual CPLErr SetMetadataItem( const char * pszName,
600                                  const char * pszValue,
601                                  const char * pszDomain = "" ) override;
602     virtual CPLErr SetMetadata( char ** papszMetadata,
603                              const char * pszDomain = "" ) override;
604 
605     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
606                                int nBufXSize, int nBufYSize,
607                                GDALDataType eDT,
608                                int nBandCount, int *panBandList,
609                                char **papszOptions ) override;
610 
611     // progressive methods
612 #if ECWSDK_VERSION >= 40
613     virtual GDALAsyncReader* BeginAsyncReader( int nXOff, int nYOff,
614                                                int nXSize, int nYSize,
615                                                void *pBuf,
616                                                int nBufXSize, int nBufYSize,
617                                                GDALDataType eBufType,
618                                                int nBandCount, int* panBandMap,
619                                                int nPixelSpace, int nLineSpace,
620                                                int nBandSpace,
621                                                char **papszOptions) override;
622 
623     virtual void EndAsyncReader(GDALAsyncReader *) override;
624 #endif /* ECWSDK_VERSION > 40 */
625 #if ECWSDK_VERSION >=50
GetFormatVersion()626     int GetFormatVersion() const {
627         return psFileInfo->nFormatVersion;
628     }
629 #endif
630 };
631 
632 /************************************************************************/
633 /* ==================================================================== */
634 /*                            ECWRasterBand                             */
635 /* ==================================================================== */
636 /************************************************************************/
637 
638 class ECWRasterBand final: public GDALPamRasterBand
639 {
640     friend class ECWDataset;
641 
642     // NOTE: poDS may be altered for NITF/JPEG2000 files!
643     ECWDataset     *poGDS;
644 
645     GDALColorInterp         eBandInterp;
646 
647     int                          iOverview; // -1 for base.
648 
649     std::vector<ECWRasterBand*>  apoOverviews;
650 
651 #if ECWSDK_VERSION>=50
652 
653     int nStatsBandIndex = 0;
654     int nStatsBandCount = 0;
655 
656 #endif
657 
658     int         bPromoteTo8Bit;
659 
660 //#if !defined(SDK_CAN_DO_SUPERSAMPLING)
661     CPLErr OldIRasterIO( GDALRWFlag, int, int, int, int,
662                               void *, int, int, GDALDataType,
663                               GSpacing nPixelSpace, GSpacing nLineSpace,
664                               GDALRasterIOExtraArg* psExtraArg );
665 //#endif
666 
667     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
668                               void *, int, int, GDALDataType,
669                               GSpacing nPixelSpace, GSpacing nLineSpace,
670                               GDALRasterIOExtraArg* psExtraArg) override;
671 
672   public:
673 
674                    ECWRasterBand( ECWDataset *, int, int iOverview, char** papszOpenOptions );
675                    ~ECWRasterBand();
676 
677     virtual CPLErr IReadBlock( int, int, void * ) override;
HasArbitraryOverviews()678     virtual int    HasArbitraryOverviews() override { return apoOverviews.empty(); }
GetOverviewCount()679     virtual int    GetOverviewCount() override { return (int)apoOverviews.size(); }
680     virtual GDALRasterBand *GetOverview(int) override;
681 
682     virtual GDALColorInterp GetColorInterpretation() override;
683     virtual CPLErr SetColorInterpretation( GDALColorInterp ) override;
684 
685     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
686                                int nBufXSize, int nBufYSize,
687                                GDALDataType eDT, char **papszOptions ) override;
688 #if ECWSDK_VERSION >= 50
689     void GetBandIndexAndCountForStatistics(int &bandIndex, int &bandCount) const;
690     virtual CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax,
691                                     int *pnBuckets, GUIntBig ** ppanHistogram,
692                                     int bForce,
693                                     GDALProgressFunc, void *pProgressData) override;
694     virtual CPLErr SetDefaultHistogram( double dfMin, double dfMax,
695                                         int nBuckets, GUIntBig *panHistogram ) override;
696     virtual double GetMinimum( int* pbSuccess ) override;
697     virtual double GetMaximum( int* pbSuccess ) override;
698     virtual CPLErr GetStatistics( int bApproxOK, int bForce,
699                                   double *pdfMin, double *pdfMax,
700                                   double *pdfMean, double *padfStdDev ) override;
701     virtual CPLErr SetStatistics( double dfMin, double dfMax,
702                                   double dfMean, double dfStdDev ) override;
703 #endif
704 
705 };
706 
707 int ECWTranslateFromWKT( const char *pszWKT,
708                          char *pszProjection,
709                          int nProjectionLen,
710                          char *pszDatum,
711                          int nDatumLen,
712                          char *pszUnits);
713 
714 CellSizeUnits ECWTranslateToCellSizeUnits(const char* pszUnits);
715 const char* ECWTranslateFromCellSizeUnits(CellSizeUnits eUnits);
716 
717 #endif /* def FRMT_ecw */
718 
719 #endif /* ndef GDAL_ECW_H_INCLUDED */
720