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