1
/******************************************************************************
2
* $Id: ecwdataset.cpp 21486 2011-01-13 17:38:17Z warmerdam $
5
* Purpose: ECW (ERDAS Wavelet Compression Format) Driver Definitions
6
* Author: Frank Warmerdam, warmerdam@pobox.com
8
******************************************************************************
9
* Copyright (c) 2001-2011, Frank Warmerdam <warmerdam@pobox.com>
11
* Permission is hereby granted, free of charge, to any person obtaining a
12
* copy of this software and associated documentation files (the "Software"),
13
* to deal in the Software without restriction, including without limitation
14
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
* and/or sell copies of the Software, and to permit persons to whom the
16
* Software is furnished to do so, subject to the following conditions:
18
* The above copyright notice and this permission notice shall be included
19
* in all copies or substantial portions of the Software.
21
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
* DEALINGS IN THE SOFTWARE.
28
****************************************************************************/
30
#ifndef GDAL_ECW_H_INCLUDED
31
#define GDAL_ECW_H_INCLUDED
34
#include "gdal_frmts.h"
35
#include "gdaljp2metadata.h"
36
#include "cpl_string.h"
38
#include "cpl_multiproc.h"
45
// The following is needed on 4.x+ to enable rw support.
46
#if defined(HAVE_COMPRESS)
47
# define ECW_COMPRESS_RW_SDK_VERSION
51
# pragma warning(disable:4800)
54
#include <NCSECWClient.h>
55
#include <NCSECWCompressClient.h>
56
#include <NCSErrors.h>
58
#include <NCSJP2FileView.h>
60
/* By default, assume 3.3 SDK Version. */
61
#if !defined(ECWSDK_VERSION)
62
# define ECWSDK_VERSION 33
65
#if ECWSDK_VERSION < 40
67
#if !defined(NO_COMPRESS)
68
# define HAVE_COMPRESS
71
# include <NCSJP2File.h>
73
# include <ECWJP2BuildNumber.h>
74
# include <HeaderEditor.h>
79
# include <NCSJP2FileView.h>
81
# undef CNCSJP2FileView
82
# define CNCSJP2FileView CNCSFile
85
void ECWInitialize( void );
86
GDALDataset* ECWDatasetOpenJPEG2000(GDALOpenInfo* poOpenInfo);
90
ECWCreateCopyECW( const char * pszFilename, GDALDataset *poSrcDS,
91
int bStrict, char ** papszOptions,
92
GDALProgressFunc pfnProgress, void * pProgressData );
94
ECWCreateCopyJPEG2000( const char * pszFilename, GDALDataset *poSrcDS,
95
int bStrict, char ** papszOptions,
96
GDALProgressFunc pfnProgress, void * pProgressData );
99
ECWCreateECW( const char * pszFilename, int nXSize, int nYSize, int nBands,
100
GDALDataType eType, char **papszOptions );
102
ECWCreateJPEG2000(const char *pszFilename, int nXSize, int nYSize, int nBands,
103
GDALDataType eType, char **papszOptions );
106
/************************************************************************/
107
/* ==================================================================== */
109
/* ==================================================================== */
110
/************************************************************************/
112
class JP2UserBox : public CNCSJP2Box {
116
unsigned char *pabyData;
121
virtual ~JP2UserBox();
123
#if ECWSDK_VERSION >= 40
124
virtual CNCSError Parse( NCS::JP2::CFile &JP2File,
125
NCS::CIOStream &Stream);
126
virtual CNCSError UnParse( NCS::JP2::CFile &JP2File,
127
NCS::CIOStream &Stream);
129
virtual CNCSError Parse(class CNCSJP2File &JP2File,
130
CNCSJPCIOStream &Stream);
131
virtual CNCSError UnParse(class CNCSJP2File &JP2File,
132
CNCSJPCIOStream &Stream);
134
virtual void UpdateXLBox(void);
136
void SetData( int nDataLength, const unsigned char *pabyDataIn );
138
int GetDataLength() { return nDataLength; }
139
unsigned char *GetData() { return pabyData; }
141
#endif /* def HAVE_COMPRESS */
143
/************************************************************************/
144
/* ==================================================================== */
146
/* ==================================================================== */
147
/************************************************************************/
149
class VSIIOStream : public CNCSJPCIOStream
155
INT64 lengthOfJPData;
167
virtual ~VSIIOStream() {
171
virtual CNCSError Close() {
172
CNCSError oErr = CNCSJPCIOStream::Close();
175
VSIFCloseL( fpVSIL );
181
#if ECWSDK_VERSION >= 40
182
virtual NCS::CIOStream *Clone() { return NULL; }
183
#endif /* ECWSDK_VERSION >= 4 */
185
virtual CNCSError Access( VSILFILE *fpVSILIn, BOOLEAN bWrite,
186
const char *pszFilename,
187
INT64 start, INT64 size = -1) {
190
startOfJPData = start;
191
lengthOfJPData = size;
193
VSIFSeekL(fpVSIL, startOfJPData, SEEK_SET);
195
// the filename is used to establish where to put temporary files.
196
// if it does not have a path to a real directory, we will
197
// substitute something.
198
CPLString osFilenameUsed = pszFilename;
199
CPLString osPath = CPLGetPath( pszFilename );
200
struct stat sStatBuf;
201
if( osPath != "" && stat( osPath, &sStatBuf ) != 0 )
203
osFilenameUsed = CPLGenerateTempFilename( NULL );
204
// try to preserve the extension.
205
if( strlen(CPLGetExtension(pszFilename)) > 0 )
207
osFilenameUsed += ".";
208
osFilenameUsed += CPLGetExtension(pszFilename);
210
CPLDebug( "ECW", "Using filename '%s' for temporary directory determination purposes.", osFilenameUsed.c_str() );
212
return(CNCSJPCIOStream::Open((char *)osFilenameUsed.c_str(),
216
virtual bool NCS_FASTCALL Seek() {
220
virtual bool NCS_FASTCALL Seek(INT64 offset, Origin origin = CURRENT) {
221
bool success = false;
224
success = (0 == VSIFSeekL(fpVSIL, offset+startOfJPData, SEEK_SET));
228
success = (0 == VSIFSeekL(fpVSIL, offset, SEEK_CUR));
232
success = (0 == VSIFSeekL(fpVSIL, offset, SEEK_END));
236
CPLDebug( "ECW", "VSIIOStream::Seek(%d,%d) failed.",
237
(int) offset, (int) origin );
241
virtual INT64 NCS_FASTCALL Tell() {
242
return VSIFTellL( fpVSIL ) - startOfJPData;
245
virtual INT64 NCS_FASTCALL Size() {
246
if( lengthOfJPData != -1 )
247
return lengthOfJPData;
250
INT64 curPos = Tell(), size;
254
Seek( curPos, START );
260
virtual bool NCS_FASTCALL Read(void* buffer, UINT32 count) {
264
// return(1 == VSIFReadL( buffer, count, 1, fpVSIL ) );
266
// The following is a hack
267
if( VSIFReadL( buffer, count, 1, fpVSIL ) != 1 )
269
CPLDebug( "VSIIOSTREAM",
270
"Read(%d) failed @ " CPL_FRMT_GIB ", ignoring failure.",
271
count, (VSIFTellL( fpVSIL ) - startOfJPData) );
277
virtual bool NCS_FASTCALL Write(void* buffer, UINT32 count) {
280
if( 1 != VSIFWriteL(buffer, count, 1, fpVSIL) )
282
CPLDebug( "ECW", "VSIIOStream::Write(%d) failed.",
291
/************************************************************************/
292
/* ==================================================================== */
294
/* ==================================================================== */
295
/************************************************************************/
298
#if ECWSDK_VERSION >= 40
300
class ECWAsyncReader : public GDALAsyncReader
303
CNCSJP2FileView *poFileView;
305
int bUsingCustomStream;
310
static NCSEcwReadStatus RefreshCB( NCSFileView * );
311
NCSEcwReadStatus ReadToBuffer();
315
virtual ~ECWAsyncReader();
316
virtual GDALAsyncStatusType GetNextUpdatedRegion(double dfTimeout,
322
friend class ECWDataset;
324
#endif /* ECWSDK_VERSION >= 40 */
326
/************************************************************************/
327
/* ==================================================================== */
329
/* ==================================================================== */
330
/************************************************************************/
334
class CPL_DLL ECWDataset : public GDALPamDataset
336
friend class ECWRasterBand;
337
friend class ECWAsyncReader;
341
CNCSJP2FileView *poFileView;
342
NCSFileViewFileInfoEx *psFileInfo;
344
GDALDataType eRasterDataType;
345
NCSEcwCellType eNCSRequestDataType;
347
int bUsingCustomStream;
349
// Current view window.
351
int nWinXOff, nWinYOff, nWinXSize, nWinYSize;
352
int nWinBufXSize, nWinBufYSize;
356
void **papCurLineBuf;
358
int bGeoTransformValid;
359
double adfGeoTransform[6];
362
GDAL_GCP *pasGCPList;
364
char **papszGMLMetadata;
366
void ECW2WKTProjection();
368
void CleanupWindow();
369
int TryWinRasterIO( GDALRWFlag, int, int, int, int,
370
GByte *, int, int, GDALDataType,
371
int, int *, int, int, int );
372
CPLErr LoadNextLine();
374
static CNCSJP2FileView *OpenFileView( const char *pszDatasetName,
376
int &bUsingCustomStream );
379
CPLString m_osDatumCode;
380
CPLString m_osProjCode;
381
CPLString m_osUnitsCode;
382
int bGeoTransformChanged;
383
int bProjectionChanged;
384
int bProjCodeChanged;
385
int bDatumCodeChanged;
386
int bUnitsCodeChanged;
389
CPLStringList oECWMetadataList;
392
ECWDataset(int bIsJPEG2000);
395
static GDALDataset *Open( GDALOpenInfo *, int bIsJPEG2000 );
396
static int IdentifyJPEG2000( GDALOpenInfo * poOpenInfo );
397
static GDALDataset *OpenJPEG2000( GDALOpenInfo * );
398
static int IdentifyECW( GDALOpenInfo * poOpenInfo );
399
static GDALDataset *OpenECW( GDALOpenInfo * );
401
virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
402
void *, int, int, GDALDataType,
403
int, int *, int, int, int );
405
virtual CPLErr GetGeoTransform( double * );
406
virtual const char *GetProjectionRef();
408
virtual int GetGCPCount();
409
virtual const char *GetGCPProjection();
410
virtual const GDAL_GCP *GetGCPs();
412
virtual const char *GetMetadataItem( const char * pszName,
413
const char * pszDomain = "" );
414
virtual char **GetMetadata( const char * pszDomain = "" );
416
virtual CPLErr SetGeoTransform( double * padfGeoTransform );
417
virtual CPLErr SetProjection( const char* pszProjection );
418
virtual CPLErr SetMetadataItem( const char * pszName,
419
const char * pszValue,
420
const char * pszDomain = "" );
421
virtual CPLErr SetMetadata( char ** papszMetadata,
422
const char * pszDomain = "" );
424
virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
425
int nBufXSize, int nBufYSize,
427
int nBandCount, int *panBandList,
428
char **papszOptions );
430
// progressive methods
431
#if ECWSDK_VERSION >= 40
432
virtual GDALAsyncReader* BeginAsyncReader( int nXOff, int nYOff,
433
int nXSize, int nYSize,
435
int nBufXSize, int nBufYSize,
436
GDALDataType eBufType,
437
int nBandCount, int* panBandMap,
438
int nPixelSpace, int nLineSpace,
440
char **papszOptions);
442
virtual void EndAsyncReader(GDALAsyncReader *);
443
#endif /* ECWSDK_VERSION > 40 */
446
/************************************************************************/
447
/* ==================================================================== */
449
/* ==================================================================== */
450
/************************************************************************/
452
class ECWRasterBand : public GDALPamRasterBand
454
friend class ECWDataset;
456
// NOTE: poDS may be altered for NITF/JPEG2000 files!
459
GDALColorInterp eBandInterp;
461
int iOverview; // -1 for base.
463
std::vector<ECWRasterBand*> apoOverviews;
465
virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
466
void *, int, int, GDALDataType,
471
ECWRasterBand( ECWDataset *, int, int = -1 );
474
virtual CPLErr IReadBlock( int, int, void * );
475
virtual int HasArbitraryOverviews() { return apoOverviews.size() == 0; }
476
virtual int GetOverviewCount() { return apoOverviews.size(); }
477
virtual GDALRasterBand *GetOverview(int);
479
virtual GDALColorInterp GetColorInterpretation();
480
virtual CPLErr SetColorInterpretation( GDALColorInterp );
482
virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
483
int nBufXSize, int nBufYSize,
484
GDALDataType eDT, char **papszOptions );
487
int ECWTranslateFromWKT( const char *pszWKT,
494
CellSizeUnits ECWTranslateToCellSizeUnits(const char* pszUnits);
495
const char* ECWTranslateFromCellSizeUnits(CellSizeUnits eUnits);
497
#endif /* def FRMT_ecw */
499
#endif /* ndef GDAL_ECW_H_INCLUDED */