1 /******************************************************************************
2  * $Id: ecwdataset.cpp 21486 2011-01-13 17:38:17Z warmerdam $
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 mines-paris dot org>
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 // The following is needed on 4.x+ to enable rw support.
46 #if defined(HAVE_COMPRESS)
47 # ifndef ECW_COMPRESS_RW_SDK_VERSION
48 #  define ECW_COMPRESS_RW_SDK_VERSION
49 # endif
50 #endif
51 
52 #if defined(_MSC_VER)
53 #  pragma warning(disable:4800)
54 #endif
55 
56 #include <NCSECWClient.h>
57 #include <NCSECWCompressClient.h>
58 #include <NCSErrors.h>
59 #include <NCSFile.h>
60 #include <NCSJP2FileView.h>
61 
62 #ifdef HAVE_ECW_BUILDNUMBER_H
63 #  include <ECWJP2BuildNumber.h>
64 #  if !defined(ECW_VERSION)
65 #    define ECWSDK_VERSION (NCS_ECWJP2_VER_MAJOR*10+NCS_ECWJP2_VER_MINOR)
66 #  endif
67 #else
68 /* By default, assume 3.3 SDK Version. */
69 #  if !defined(ECWSDK_VERSION)
70 #    define ECWSDK_VERSION 33
71 #  endif
72 #endif
73 
74 #if ECWSDK_VERSION < 40
75 
76 #if !defined(NO_COMPRESS) && !defined(HAVE_COMPRESS)
77 #  define HAVE_COMPRESS
78 #endif
79 
80 #else
81     #if ECWSDK_VERSION>=50
82 		#if ECWSDK_VERSION>=51
83 			#define JPEG2000_DOMAIN_NAME "JPEG2000"
84 		#endif
85         #include <NCSECWHeaderEditor.h>
86         #include "NCSEcw/SDK/Box.h"
87     #else
88         #include <HeaderEditor.h>
89     #endif
90 #  define NCS_FASTCALL
91 #endif
92 
93 #if ECWSDK_VERSION >= 40
94 #define SDK_CAN_DO_SUPERSAMPLING 1
95 #endif
96 
97 #ifndef NCSFILEBASE_H
98 #  include <NCSJP2FileView.h>
99 #else
100 #  undef  CNCSJP2FileView
101 #  define CNCSJP2FileView	  CNCSFile
102 #endif
103 
104 void ECWInitialize( void );
105 GDALDataset* ECWDatasetOpenJPEG2000(GDALOpenInfo* poOpenInfo);
106 const char* ECWGetColorInterpretationName(GDALColorInterp eColorInterpretation, int nBandNumber);
107 GDALColorInterp ECWGetColorInterpretationByName(const char *pszName);
108 const char* ECWGetColorSpaceName(NCSFileColorSpace colorSpace);
109 #ifdef HAVE_COMPRESS
110 GDALDataset *
111 ECWCreateCopyECW( const char * pszFilename, GDALDataset *poSrcDS,
112                  int bStrict, char ** papszOptions,
113                  GDALProgressFunc pfnProgress, void * pProgressData );
114 GDALDataset *
115 ECWCreateCopyJPEG2000( const char * pszFilename, GDALDataset *poSrcDS,
116                  int bStrict, char ** papszOptions,
117                  GDALProgressFunc pfnProgress, void * pProgressData );
118 
119 GDALDataset *
120 ECWCreateECW( const char * pszFilename, int nXSize, int nYSize, int nBands,
121               GDALDataType eType, char **papszOptions );
122 GDALDataset *
123 ECWCreateJPEG2000(const char *pszFilename, int nXSize, int nYSize, int nBands,
124                   GDALDataType eType, char **papszOptions );
125 #endif
126 
127 void ECWReportError(CNCSError& oErr, const char* pszMsg = "");
128 
129 /************************************************************************/
130 /* ==================================================================== */
131 /*                             JP2Userbox                               */
132 /* ==================================================================== */
133 /************************************************************************/
134 #ifdef HAVE_COMPRESS
135 #if ECWSDK_VERSION>=50
136 class JP2UserBox : public CNCSSDKBox {
137 #else
138 class JP2UserBox : public CNCSJP2Box {
139 #endif
140 private:
141     int           nDataLength;
142     unsigned char *pabyData;
143 
144 public:
145     JP2UserBox();
146 
147     virtual ~JP2UserBox();
148 
149 #if ECWSDK_VERSION >= 40
150     virtual CNCSError Parse(NCS::SDK::CFileBase &JP2File,
151                              NCS::CIOStream &Stream);
152     virtual CNCSError UnParse(NCS::SDK::CFileBase &JP2File,
153                                 NCS::CIOStream &Stream);
154 #else
155     virtual CNCSError Parse(class CNCSJP2File &JP2File,
156                             CNCSJPCIOStream &Stream);
157     virtual CNCSError UnParse(class CNCSJP2File &JP2File,
158                               CNCSJPCIOStream &Stream);
159 #endif
160     virtual void UpdateXLBox(void);
161 
162     void    SetData( int nDataLength, const unsigned char *pabyDataIn );
163 
GetDataLength()164     int     GetDataLength() { return nDataLength; }
GetData()165     unsigned char *GetData() { return pabyData; }
166 };
167 #endif /* def HAVE_COMPRESS */
168 
169 /************************************************************************/
170 /* ==================================================================== */
171 /*                             VSIIOStream                              */
172 /* ==================================================================== */
173 /************************************************************************/
174 
175 class VSIIOStream : public CNCSJPCIOStream
176 
177 {
178   private:
179     char     *m_Filename;
180   public:
181 
182     INT64    startOfJPData;
183     INT64    lengthOfJPData;
184     VSILFILE    *fpVSIL;
185     BOOLEAN      bWritable;
186     BOOLEAN      bSeekable;
187     int      nFileViewCount;
188 
189     int      nCOMState;
190     int      nCOMLength;
191     GByte    abyCOMType[2];
192 
VSIIOStream()193     VSIIOStream() : m_Filename(NULL){
194         nFileViewCount = 0;
195         startOfJPData = 0;
196         lengthOfJPData = -1;
197         fpVSIL = NULL;
198         bWritable = false;
199         bSeekable = false;
200         if( CSLTestBoolean(CPLGetConfigOption("GDAL_ECW_WRITE_COMPRESSION_SOFTWARE", "YES")) )
201             nCOMState = -1;
202         else
203             nCOMState = 0;
204         nCOMLength = 0;
205         abyCOMType[0] = 0;
206         abyCOMType[1] = 0;
207     }
~VSIIOStream()208     virtual ~VSIIOStream() {
209         Close();
210         if (m_Filename!=NULL){
211             CPLFree(m_Filename);
212         }
213     }
214 
Close()215     virtual CNCSError Close() {
216         CNCSError oErr = CNCSJPCIOStream::Close();
217         if( fpVSIL != NULL )
218         {
219             VSIFCloseL( fpVSIL );
220             fpVSIL = NULL;
221         }
222         return oErr;
223     }
224 
225 #if ECWSDK_VERSION >= 40
Clone()226     virtual VSIIOStream *Clone() {
227 
228         VSILFILE *fpNewVSIL = VSIFOpenL( m_Filename, "rb" );
229         if (fpNewVSIL == NULL)
230         {
231             return NULL;
232         }else
233         {
234             VSIIOStream *pDst = new VSIIOStream();
235             pDst->Access(fpNewVSIL, bWritable, bSeekable, m_Filename, startOfJPData, lengthOfJPData);
236             return pDst;
237         }
238     }
239 #endif /* ECWSDK_VERSION >= 4 */
240 
241     CNCSError Access( VSILFILE *fpVSILIn, BOOLEAN bWrite, BOOLEAN bSeekableIn,
242                               const char *pszFilename,
243                               INT64 start, INT64 size = -1) {
244 
245         fpVSIL = fpVSILIn;
246         startOfJPData = start;
247         lengthOfJPData = size;
248         bWritable = bWrite;
249         bSeekable = bSeekableIn;
250         VSIFSeekL(fpVSIL, startOfJPData, SEEK_SET);
251         m_Filename = CPLStrdup(pszFilename);
252         // the filename is used to establish where to put temporary files.
253         // if it does not have a path to a real directory, we will
254         // substitute something.
255         CPLString osFilenameUsed = pszFilename;
256         CPLString osPath = CPLGetPath( pszFilename );
257         struct stat sStatBuf;
258         if( osPath != "" && stat( osPath, &sStatBuf ) != 0 )
259         {
260             osFilenameUsed = CPLGenerateTempFilename( NULL );
261             // try to preserve the extension.
262             if( strlen(CPLGetExtension(pszFilename)) > 0 )
263             {
264                 osFilenameUsed += ".";
265                 osFilenameUsed += CPLGetExtension(pszFilename);
266             }
267             CPLDebug( "ECW", "Using filename '%s' for temporary directory determination purposes.", osFilenameUsed.c_str() );
268         }
269         return(CNCSJPCIOStream::Open((char *)osFilenameUsed.c_str(),
270                                      (bool) bWrite));
271     }
272 
Seek()273     virtual bool NCS_FASTCALL Seek() {
274         return bSeekable;
275     }
276 
277     virtual bool NCS_FASTCALL Seek(INT64 offset, Origin origin = CURRENT) {
278         bool success = false;
279         switch(origin) {
280             case START:
281               success = (0 == VSIFSeekL(fpVSIL, offset+startOfJPData, SEEK_SET));
282               break;
283 
284             case CURRENT:
285               success = (0 == VSIFSeekL(fpVSIL, offset, SEEK_CUR));
286               break;
287 
288             case END:
289               success = (0 == VSIFSeekL(fpVSIL, offset, SEEK_END));
290               break;
291         }
292         if( !success )
293             CPLDebug( "ECW", "VSIIOStream::Seek(%d,%d) failed.",
294                       (int) offset, (int) origin );
295         return(success);
296     }
297 
Tell()298     virtual INT64 NCS_FASTCALL Tell() {
299         return VSIFTellL( fpVSIL ) - startOfJPData;
300     }
301 
Size()302     virtual INT64 NCS_FASTCALL Size() {
303         if( lengthOfJPData != -1 )
304             return lengthOfJPData;
305         else
306         {
307             INT64 curPos = Tell(), size;
308 
309             Seek( 0, END );
310             size = Tell();
311             Seek( curPos, START );
312 
313             return size;
314         }
315     }
316 
Read(void * buffer,UINT32 count)317     virtual bool NCS_FASTCALL Read(void* buffer, UINT32 count) {
318         if( count == 0 )
319             return true;
320 
321 //        return(1 == VSIFReadL( buffer, count, 1, fpVSIL ) );
322 
323         // The following is a hack
324         if( VSIFReadL( buffer, count, 1, fpVSIL ) != 1 )
325         {
326             CPLDebug( "VSIIOSTREAM",
327                       "Read(%d) failed @ " CPL_FRMT_GIB ", ignoring failure.",
328                       count, (VSIFTellL( fpVSIL ) - startOfJPData) );
329         }
330 
331         return true;
332     }
333 
Write(void * buffer,UINT32 count)334     virtual bool NCS_FASTCALL Write(void* buffer, UINT32 count) {
335         if( count == 0 )
336             return true;
337 
338         GByte* paby = (GByte*) buffer;
339         if( nCOMState == 0 )
340         {
341             if( count == 2 && paby[0] == 0xff && paby[1] == 0x64 )
342             {
343                 nCOMState ++;
344                 return true;
345             }
346         }
347         else if( nCOMState == 1 )
348         {
349             if( count == 2 )
350             {
351                 nCOMLength = (paby[0] << 8) | paby[1];
352                 nCOMState ++;
353                 return true;
354             }
355             else
356             {
357                 GByte prevBuffer[] = { 0xff, 0x64 };
358                 VSIFWriteL(prevBuffer, 2, 1, fpVSIL);
359                 nCOMState = 0;
360             }
361         }
362         else if( nCOMState == 2 )
363         {
364             if( count == 2 )
365             {
366                 abyCOMType[0] = paby[0];
367                 abyCOMType[1] = paby[1];
368                 nCOMState ++;
369                 return true;
370             }
371             else
372             {
373                 GByte prevBuffer[] =
374 		  { (GByte)(nCOMLength >> 8), (GByte) (nCOMLength & 0xff) };
375                 VSIFWriteL(prevBuffer, 2, 1, fpVSIL);
376                 nCOMState = 0;
377             }
378         }
379         else if( nCOMState == 3 )
380         {
381             if( count == (UINT32)nCOMLength - 4 )
382             {
383                 nCOMState = 0;
384                 return true;
385             }
386             else
387             {
388                 VSIFWriteL(abyCOMType, 2, 1, fpVSIL);
389                 nCOMState = 0;
390             }
391         }
392 
393         if( 1 != VSIFWriteL(buffer, count, 1, fpVSIL) )
394         {
395             CPLDebug( "ECW", "VSIIOStream::Write(%d) failed.",
396                       (int) count );
397             return false;
398         }
399         else
400             return true;
401     }
402 };
403 
404 /************************************************************************/
405 /* ==================================================================== */
406 /*                            ECWAsyncReader                            */
407 /* ==================================================================== */
408 /************************************************************************/
409 class ECWDataset;
410 
411 #if ECWSDK_VERSION >= 40
412 
413 class ECWAsyncReader : public GDALAsyncReader
414 {
415 private:
416     CNCSJP2FileView *poFileView;
417     CPLMutex        *hMutex;
418     int              bUsingCustomStream;
419 
420     int              bUpdateReady;
421     int              bComplete;
422 
423     static NCSEcwReadStatus RefreshCB( NCSFileView * );
424     NCSEcwReadStatus ReadToBuffer();
425 
426 public:
427     ECWAsyncReader();
428     virtual ~ECWAsyncReader();
429     virtual GDALAsyncStatusType GetNextUpdatedRegion(double dfTimeout,
430                                                      int* pnXBufOff,
431                                                      int* pnYBufOff,
432                                                      int* pnXBufSize,
433                                                      int* pnYBufSize);
434 
435     friend class ECWDataset;
436 };
437 #endif /* ECWSDK_VERSION >= 40 */
438 
439 /************************************************************************/
440 /* ==================================================================== */
441 /*				ECWDataset				*/
442 /* ==================================================================== */
443 /************************************************************************/
444 
445 class ECWRasterBand;
446 
447 typedef struct
448 {
449     int bEnabled;
450     int nBandsTried;
451 
452     int nXOff;
453     int nYOff;
454     int nXSize;
455     int nYSize;
456     int nBufXSize;
457     int nBufYSize;
458     GDALDataType eBufType;
459     GByte* pabyData;
460 } ECWCachedMultiBandIO;
461 
462 class CPL_DLL ECWDataset : public GDALJP2AbstractDataset
463 {
464     friend class ECWRasterBand;
465     friend class ECWAsyncReader;
466 
467     int         bIsJPEG2000;
468 
469     CNCSJP2FileView *poFileView;
470     NCSFileViewFileInfoEx *psFileInfo;
471 
472     GDALDataType eRasterDataType;
473     NCSEcwCellType eNCSRequestDataType;
474 
475     int         bUsingCustomStream;
476 
477     // Current view window.
478     int         bWinActive;
479     int         nWinXOff, nWinYOff, nWinXSize, nWinYSize;
480     int         nWinBufXSize, nWinBufYSize;
481     int         nWinBandCount;
482     int         *panWinBandList;
483     int         nWinBufLoaded;
484     void        **papCurLineBuf;
485 
486     char        **papszGMLMetadata;
487 
488     ECWCachedMultiBandIO sCachedMultiBandIO;
489 
490     void        ECW2WKTProjection();
491 
492     void        CleanupWindow();
493     int         TryWinRasterIO( GDALRWFlag, int, int, int, int,
494                                 GByte *, int, int, GDALDataType,
495                                 int, int *,
496                                 GSpacing nPixelSpace, GSpacing nLineSpace,
497                                 GSpacing nBandSpace,
498                                 GDALRasterIOExtraArg* psExtraArg );
499     CPLErr      LoadNextLine();
500 
501 #if ECWSDK_VERSION>=50
502 
503     NCSFileStatistics* pStatistics;
504     int bStatisticsDirty;
505     int bStatisticsInitialized;
506     NCS::CError StatisticsEnsureInitialized();
507     NCS::CError StatisticsWrite();
508     void CleanupStatistics();
509 	void ReadFileMetaDataFromFile();
510 
511     int bFileMetaDataDirty;
512     void WriteFileMetaData(NCSFileMetaData* pFileMetaDataCopy);
513 
514 #endif
515 
516     static CNCSJP2FileView    *OpenFileView( const char *pszDatasetName,
517                                              bool bProgressive,
518                                              int &bUsingCustomStream,
519                                              bool bWrite=false);
520 
521     int         bHdrDirty;
522     CPLString   m_osDatumCode;
523     CPLString   m_osProjCode;
524     CPLString   m_osUnitsCode;
525     int         bGeoTransformChanged;
526     int         bProjectionChanged;
527     int         bProjCodeChanged;
528     int         bDatumCodeChanged;
529     int         bUnitsCodeChanged;
530     void        WriteHeader();
531 
532     int         bUseOldBandRasterIOImplementation;
533 
534     int         bPreventCopyingSomeMetadata;
535 
536     int         nBandIndexToPromoteTo8Bit;
537 
538     CPLStringList oECWMetadataList;
539     CPLErr ReadBands(void * pData, int nBufXSize, int nBufYSize,
540                     GDALDataType eBufType,
541                     int nBandCount,
542                     GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace,
543                     GDALRasterIOExtraArg* psExtraArg);
544     CPLErr ReadBandsDirectly(void * pData, int nBufXSize, int nBufYSize,
545                     GDALDataType eBufType,
546                     int nBandCount,
547                     GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace,
548                     GDALRasterIOExtraArg* psExtraArg);
549   public:
550         ECWDataset(int bIsJPEG2000);
551         ~ECWDataset();
552 
553     static GDALDataset *Open( GDALOpenInfo *, int bIsJPEG2000 );
554     static int          IdentifyJPEG2000( GDALOpenInfo * poOpenInfo );
555     static GDALDataset *OpenJPEG2000( GDALOpenInfo * );
556     static int          IdentifyECW( GDALOpenInfo * poOpenInfo );
557     static GDALDataset *OpenECW( GDALOpenInfo * );
558 
SetPreventCopyingSomeMetadata(int b)559     void        SetPreventCopyingSomeMetadata(int b) { bPreventCopyingSomeMetadata = b; }
560 
561     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
562                               void *, int, int, GDALDataType,
563                               int, int *,
564                               GSpacing nPixelSpace, GSpacing nLineSpace,
565                               GSpacing nBandSpace,
566                               GDALRasterIOExtraArg* psExtraArg);
567 
568     virtual char      **GetMetadataDomainList();
569     virtual const char *GetMetadataItem( const char * pszName,
570                                      const char * pszDomain = "" );
571     virtual char      **GetMetadata( const char * pszDomain = "" );
572 
573     virtual CPLErr SetGeoTransform( double * padfGeoTransform );
574     virtual CPLErr SetProjection( const char* pszProjection );
575     virtual CPLErr SetMetadataItem( const char * pszName,
576                                  const char * pszValue,
577                                  const char * pszDomain = "" );
578     virtual CPLErr SetMetadata( char ** papszMetadata,
579                              const char * pszDomain = "" );
580 
581     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
582                                int nBufXSize, int nBufYSize,
583                                GDALDataType eDT,
584                                int nBandCount, int *panBandList,
585                                char **papszOptions );
586 
587     // progressive methods
588 #if ECWSDK_VERSION >= 40
589     virtual GDALAsyncReader* BeginAsyncReader( int nXOff, int nYOff,
590                                                int nXSize, int nYSize,
591                                                void *pBuf,
592                                                int nBufXSize, int nBufYSize,
593                                                GDALDataType eBufType,
594                                                int nBandCount, int* panBandMap,
595                                                int nPixelSpace, int nLineSpace,
596                                                int nBandSpace,
597                                                char **papszOptions);
598 
599     virtual void EndAsyncReader(GDALAsyncReader *);
600 #endif /* ECWSDK_VERSION > 40 */
601 #if ECWSDK_VERSION >=50
GetFormatVersion()602     int GetFormatVersion() const {
603         return psFileInfo->nFormatVersion;
604     }
605 #endif
606 };
607 
608 /************************************************************************/
609 /* ==================================================================== */
610 /*                            ECWRasterBand                             */
611 /* ==================================================================== */
612 /************************************************************************/
613 
614 class ECWRasterBand : public GDALPamRasterBand
615 {
616     friend class ECWDataset;
617 
618     // NOTE: poDS may be altered for NITF/JPEG2000 files!
619     ECWDataset     *poGDS;
620 
621     GDALColorInterp         eBandInterp;
622 
623     int                          iOverview; // -1 for base.
624 
625     std::vector<ECWRasterBand*>  apoOverviews;
626 
627 #if ECWSDK_VERSION>=50
628 
629     int nStatsBandIndex;
630     int nStatsBandCount;
631 
632 #endif
633 
634     int         bPromoteTo8Bit;
635 
636 //#if !defined(SDK_CAN_DO_SUPERSAMPLING)
637     CPLErr OldIRasterIO( GDALRWFlag, int, int, int, int,
638                               void *, int, int, GDALDataType,
639                               GSpacing nPixelSpace, GSpacing nLineSpace,
640                               GDALRasterIOExtraArg* psExtraArg );
641 //#endif
642 
643     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
644                               void *, int, int, GDALDataType,
645                               GSpacing nPixelSpace, GSpacing nLineSpace,
646                               GDALRasterIOExtraArg* psExtraArg);
647 
648   public:
649 
650                    ECWRasterBand( ECWDataset *, int, int iOverview, char** papszOpenOptions );
651                    ~ECWRasterBand();
652 
653     virtual CPLErr IReadBlock( int, int, void * );
HasArbitraryOverviews()654     virtual int    HasArbitraryOverviews() { return apoOverviews.size() == 0; }
GetOverviewCount()655     virtual int    GetOverviewCount() { return (int)apoOverviews.size(); }
656     virtual GDALRasterBand *GetOverview(int);
657 
658     virtual GDALColorInterp GetColorInterpretation();
659     virtual CPLErr SetColorInterpretation( GDALColorInterp );
660 
661     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
662                                int nBufXSize, int nBufYSize,
663                                GDALDataType eDT, char **papszOptions );
664 #if ECWSDK_VERSION >= 50
665     void GetBandIndexAndCountForStatistics(int &bandIndex, int &bandCount);
666     virtual CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax,
667                                     int *pnBuckets, GUIntBig ** ppanHistogram,
668                                     int bForce,
669                                     GDALProgressFunc, void *pProgressData);
670     virtual CPLErr SetDefaultHistogram( double dfMin, double dfMax,
671                                         int nBuckets, GUIntBig *panHistogram );
672     virtual double GetMinimum( int* pbSuccess );
673     virtual double GetMaximum( int* pbSuccess );
674     virtual CPLErr GetStatistics( int bApproxOK, int bForce,
675                                   double *pdfMin, double *pdfMax,
676                                   double *pdfMean, double *padfStdDev );
677     virtual CPLErr SetStatistics( double dfMin, double dfMax,
678                                   double dfMean, double dfStdDev );
679 #endif
680 
681 };
682 
683 int ECWTranslateFromWKT( const char *pszWKT,
684                          char *pszProjection,
685                          int nProjectionLen,
686                          char *pszDatum,
687                          int nDatumLen,
688                          char *pszUnits);
689 
690 CellSizeUnits ECWTranslateToCellSizeUnits(const char* pszUnits);
691 const char* ECWTranslateFromCellSizeUnits(CellSizeUnits eUnits);
692 
693 #endif /* def FRMT_ecw */
694 
695 #endif /* ndef GDAL_ECW_H_INCLUDED */
696