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, static_cast<vsi_l_offset>(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 2606 : success = (0 == VSIFSeekL(fpVSIL,
272 1303 : static_cast<vsi_l_offset>(offset) +
273 1303 : startOfJPData,
274 : SEEK_SET));
275 1303 : break;
276 :
277 0 : case CURRENT:
278 0 : success =
279 0 : (0 == VSIFSeekL(fpVSIL, static_cast<vsi_l_offset>(offset),
280 : SEEK_CUR));
281 0 : break;
282 :
283 286 : case END:
284 286 : success =
285 286 : (0 == VSIFSeekL(fpVSIL, static_cast<vsi_l_offset>(offset),
286 : SEEK_END));
287 286 : break;
288 : }
289 1589 : if (!success)
290 0 : CPLDebug("ECW", "VSIIOStream::Seek(%d,%d) failed.", (int)offset,
291 : (int)origin);
292 1589 : return (success);
293 : }
294 :
295 6027 : INT64 NCS_FASTCALL Tell() override
296 : {
297 6027 : return VSIFTellL(fpVSIL) - startOfJPData;
298 : }
299 :
300 286 : INT64 NCS_FASTCALL Size() override
301 : {
302 286 : if (lengthOfJPData != -1)
303 0 : return lengthOfJPData;
304 : else
305 : {
306 286 : INT64 curPos = Tell(), size;
307 :
308 286 : Seek(0, END);
309 286 : size = Tell();
310 286 : Seek(curPos, START);
311 : #ifdef DEBUG_VERBOSE
312 : CPLDebug("ECW", "VSIIOStream::Size()=" CPL_FRMT_GIB,
313 : static_cast<GIntBig>(size));
314 : #endif
315 286 : return size;
316 : }
317 : }
318 :
319 : #if ECWSDK_VERSION >= 40
320 : /* New, and needed, in ECW SDK 4 */
321 : bool Read(INT64 offset, void *buffer, UINT32 count) override
322 : {
323 : #ifdef DEBUG_VERBOSE
324 : CPLDebug("ECW", "VSIIOStream::Read(" CPL_FRMT_GIB ",%u)",
325 : static_cast<GIntBig>(offset), count);
326 : #endif
327 : /* SDK 4.3 doc says it is not supposed to update the file pointer. */
328 : /* Later versions have no comment... */
329 : INT64 curPos = Tell();
330 : Seek(offset, START);
331 : bool ret = Read(buffer, count);
332 : Seek(curPos, START);
333 : return ret;
334 : }
335 : #endif
336 :
337 10038 : bool NCS_FASTCALL Read(void *buffer, UINT32 count) override
338 : {
339 : #ifdef DEBUG_VERBOSE
340 : CPLDebug("ECW", "VSIIOStream::Read(%u)", count);
341 : #endif
342 10038 : if (count == 0)
343 366 : return true;
344 :
345 : // return(1 == VSIFReadL( buffer, count, 1, fpVSIL ) );
346 :
347 : // The following is a hack
348 9672 : if (VSIFReadL(buffer, count, 1, fpVSIL) != 1)
349 : {
350 0 : CPLDebug("VSIIOSTREAM",
351 : "Read(%d) failed @ " CPL_FRMT_GIB ", ignoring failure.",
352 0 : count, (VSIFTellL(fpVSIL) - startOfJPData));
353 : }
354 :
355 9672 : return true;
356 : }
357 :
358 5350 : bool NCS_FASTCALL Write(void *buffer, UINT32 count) override
359 : {
360 5350 : if (count == 0)
361 0 : return true;
362 :
363 5350 : GByte *paby = (GByte *)buffer;
364 5350 : if (nCOMState == 0)
365 : {
366 0 : if (count == 2 && paby[0] == 0xff && paby[1] == 0x64)
367 : {
368 0 : nCOMState++;
369 0 : return true;
370 : }
371 : }
372 5350 : else if (nCOMState == 1)
373 : {
374 0 : if (count == 2)
375 : {
376 0 : nCOMLength = (paby[0] << 8) | paby[1];
377 0 : nCOMState++;
378 0 : return true;
379 : }
380 : else
381 : {
382 0 : GByte prevBuffer[] = {0xff, 0x64};
383 0 : VSIFWriteL(prevBuffer, 2, 1, fpVSIL);
384 0 : nCOMState = 0;
385 : }
386 : }
387 5350 : else if (nCOMState == 2)
388 : {
389 0 : if (count == 2)
390 : {
391 0 : abyCOMType[0] = paby[0];
392 0 : abyCOMType[1] = paby[1];
393 0 : nCOMState++;
394 0 : return true;
395 : }
396 : else
397 : {
398 0 : GByte prevBuffer[] = {(GByte)(nCOMLength >> 8),
399 0 : (GByte)(nCOMLength & 0xff)};
400 0 : VSIFWriteL(prevBuffer, 2, 1, fpVSIL);
401 0 : nCOMState = 0;
402 : }
403 : }
404 5350 : else if (nCOMState == 3)
405 : {
406 0 : if (count == (UINT32)nCOMLength - 4)
407 : {
408 0 : nCOMState = 0;
409 0 : return true;
410 : }
411 : else
412 : {
413 0 : VSIFWriteL(abyCOMType, 2, 1, fpVSIL);
414 0 : nCOMState = 0;
415 : }
416 : }
417 :
418 5350 : if (1 != VSIFWriteL(buffer, count, 1, fpVSIL))
419 : {
420 0 : CPLDebug("ECW", "VSIIOStream::Write(%d) failed.", (int)count);
421 0 : return false;
422 : }
423 : else
424 5350 : return true;
425 : }
426 : };
427 :
428 : /************************************************************************/
429 : /* ==================================================================== */
430 : /* ECWAsyncReader */
431 : /* ==================================================================== */
432 : /************************************************************************/
433 : class ECWDataset;
434 :
435 : #if ECWSDK_VERSION >= 40
436 :
437 : class ECWAsyncReader final : public GDALAsyncReader
438 : {
439 : private:
440 : CNCSJP2FileView *poFileView = nullptr;
441 : CPLMutex *hMutex = nullptr;
442 : int bUsingCustomStream = false;
443 :
444 : int bUpdateReady = false;
445 : int bComplete = false;
446 :
447 : static NCSEcwReadStatus RefreshCB(NCSFileView *);
448 : NCSEcwReadStatus ReadToBuffer();
449 :
450 : public:
451 : ECWAsyncReader();
452 : ~ECWAsyncReader() override;
453 : virtual GDALAsyncStatusType
454 : GetNextUpdatedRegion(double dfTimeout, int *pnXBufOff, int *pnYBufOff,
455 : int *pnXBufSize, int *pnYBufSize) override;
456 :
457 : friend class ECWDataset;
458 : };
459 : #endif /* ECWSDK_VERSION >= 40 */
460 :
461 : /************************************************************************/
462 : /* ==================================================================== */
463 : /* ECWDataset */
464 : /* ==================================================================== */
465 : /************************************************************************/
466 :
467 : class ECWRasterBand;
468 :
469 : typedef struct
470 : {
471 : int bEnabled;
472 : int nBandsTried;
473 :
474 : int nXOff;
475 : int nYOff;
476 : int nXSize;
477 : int nYSize;
478 : int nBufXSize;
479 : int nBufYSize;
480 : GDALDataType eBufType;
481 : GByte *pabyData;
482 : } ECWCachedMultiBandIO;
483 :
484 : class CPL_DLL ECWDataset final : public GDALJP2AbstractDataset
485 : {
486 : friend class ECWRasterBand;
487 : friend class ECWAsyncReader;
488 :
489 : int bIsJPEG2000;
490 :
491 : CNCSJP2FileView *poFileView;
492 : NCSFileViewFileInfoEx *psFileInfo;
493 :
494 : GDALDataType eRasterDataType;
495 : NCSEcwCellType eNCSRequestDataType;
496 :
497 : int bUsingCustomStream;
498 :
499 : // Current view window.
500 : int bWinActive;
501 : int nWinXOff, nWinYOff, nWinXSize, nWinYSize;
502 : int nWinBufXSize, nWinBufYSize;
503 : int nWinBandCount;
504 : int *panWinBandList;
505 : int nWinBufLoaded;
506 : void **papCurLineBuf;
507 :
508 : // Deferred advise read parameters
509 : int m_nAdviseReadXOff;
510 : int m_nAdviseReadYOff;
511 : int m_nAdviseReadXSize;
512 : int m_nAdviseReadYSize;
513 : int m_nAdviseReadBufXSize;
514 : int m_nAdviseReadBufYSize;
515 : int m_nAdviseReadBandCount;
516 : int *m_panAdviseReadBandList;
517 :
518 : char **papszGMLMetadata;
519 :
520 : ECWCachedMultiBandIO sCachedMultiBandIO;
521 :
522 : void ECW2WKTProjection();
523 :
524 : void CleanupWindow();
525 : CPLErr RunDeferredAdviseRead();
526 : int TryWinRasterIO(GDALRWFlag, int, int, int, int, GByte *, int, int,
527 : GDALDataType, int, const int *, GSpacing nPixelSpace,
528 : GSpacing nLineSpace, GSpacing nBandSpace,
529 : GDALRasterIOExtraArg *psExtraArg);
530 : CPLErr LoadNextLine();
531 :
532 : #if ECWSDK_VERSION >= 50
533 :
534 : NCSFileStatistics *pStatistics;
535 : int bStatisticsDirty;
536 : int bStatisticsInitialized;
537 : NCS::CError StatisticsEnsureInitialized();
538 : NCS::CError StatisticsWrite();
539 : void CleanupStatistics();
540 : void ReadFileMetaDataFromFile();
541 :
542 : int bFileMetaDataDirty;
543 : void WriteFileMetaData(NCSFileMetaData *pFileMetaDataCopy);
544 :
545 : #endif
546 :
547 : static CNCSJP2FileView *OpenFileView(const char *pszDatasetName,
548 : bool bProgressive,
549 : int &bUsingCustomStream,
550 : bool bWrite = false);
551 :
552 : int bHdrDirty;
553 : CPLString m_osDatumCode;
554 : CPLString m_osProjCode;
555 : CPLString m_osUnitsCode;
556 : int bGeoTransformChanged;
557 : int bProjectionChanged;
558 : int bProjCodeChanged;
559 : int bDatumCodeChanged;
560 : int bUnitsCodeChanged;
561 : void WriteHeader();
562 :
563 : int bUseOldBandRasterIOImplementation;
564 :
565 : int bPreventCopyingSomeMetadata;
566 :
567 : int nBandIndexToPromoteTo8Bit;
568 :
569 : CPLStringList oECWMetadataList;
570 : CPLErr ReadBands(void *pData, int nBufXSize, int nBufYSize,
571 : GDALDataType eBufType, int nBandCount,
572 : GSpacing nPixelSpace, GSpacing nLineSpace,
573 : GSpacing nBandSpace, GDALRasterIOExtraArg *psExtraArg);
574 : CPLErr ReadBandsDirectly(void *pData, int nBufXSize, int nBufYSize,
575 : GDALDataType eBufType, int nBandCount,
576 : GSpacing nPixelSpace, GSpacing nLineSpace,
577 : GSpacing nBandSpace,
578 : GDALRasterIOExtraArg *psExtraArg);
579 :
580 : public:
581 : explicit ECWDataset(int bIsJPEG2000);
582 : ~ECWDataset() override;
583 :
584 : static GDALDataset *Open(GDALOpenInfo *, int bIsJPEG2000);
585 : static GDALDataset *OpenJPEG2000(GDALOpenInfo *);
586 : static GDALDataset *OpenECW(GDALOpenInfo *);
587 :
588 64 : void SetPreventCopyingSomeMetadata(int b)
589 : {
590 64 : bPreventCopyingSomeMetadata = b;
591 64 : }
592 :
593 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
594 : GDALDataType, int, BANDMAP_TYPE, GSpacing nPixelSpace,
595 : GSpacing nLineSpace, GSpacing nBandSpace,
596 : GDALRasterIOExtraArg *psExtraArg) override;
597 :
598 : char **GetMetadataDomainList() override;
599 : virtual const char *GetMetadataItem(const char *pszName,
600 : const char *pszDomain = "") override;
601 : char **GetMetadata(const char *pszDomain = "") override;
602 :
603 : CPLErr SetGeoTransform(const GDALGeoTransform >) override;
604 : CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
605 :
606 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
607 : const char *pszDomain = "") override;
608 : CPLErr SetMetadata(char **papszMetadata,
609 : const char *pszDomain = "") override;
610 :
611 : CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
612 : int nBufXSize, int nBufYSize, GDALDataType eDT,
613 : int nBandCount, int *panBandList,
614 : char **papszOptions) override;
615 :
616 : // progressive methods
617 : #if ECWSDK_VERSION >= 40
618 : virtual GDALAsyncReader *
619 : BeginAsyncReader(int nXOff, int nYOff, int nXSize, int nYSize, void *pBuf,
620 : int nBufXSize, int nBufYSize, GDALDataType eBufType,
621 : int nBandCount, int *panBandMap, int nPixelSpace,
622 : int nLineSpace, int nBandSpace,
623 : char **papszOptions) override;
624 :
625 : void EndAsyncReader(GDALAsyncReader *) override;
626 : #endif /* ECWSDK_VERSION > 40 */
627 : #if ECWSDK_VERSION >= 50
628 : int GetFormatVersion() const
629 : {
630 : return psFileInfo->nFormatVersion;
631 : }
632 : #endif
633 : };
634 :
635 : /************************************************************************/
636 : /* ==================================================================== */
637 : /* ECWRasterBand */
638 : /* ==================================================================== */
639 : /************************************************************************/
640 :
641 : class ECWRasterBand final : public GDALPamRasterBand
642 : {
643 : friend class ECWDataset;
644 :
645 : // NOTE: poDS may be altered for NITF/JPEG2000 files!
646 : ECWDataset *poGDS;
647 :
648 : GDALColorInterp eBandInterp;
649 :
650 : int iOverview; // -1 for base.
651 :
652 : std::vector<ECWRasterBand *> apoOverviews;
653 :
654 : #if ECWSDK_VERSION >= 50
655 :
656 : int nStatsBandIndex = 0;
657 : int nStatsBandCount = 0;
658 :
659 : #endif
660 :
661 : int bPromoteTo8Bit;
662 :
663 : // #if !defined(SDK_CAN_DO_SUPERSAMPLING)
664 : CPLErr OldIRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
665 : GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace,
666 : GDALRasterIOExtraArg *psExtraArg);
667 : // #endif
668 :
669 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
670 : GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace,
671 : GDALRasterIOExtraArg *psExtraArg) override;
672 :
673 : public:
674 : ECWRasterBand(ECWDataset *, int, int iOverview, char **papszOpenOptions);
675 : ~ECWRasterBand() override;
676 :
677 : CPLErr IReadBlock(int, int, void *) override;
678 :
679 0 : int HasArbitraryOverviews() override
680 : {
681 0 : return apoOverviews.empty();
682 : }
683 :
684 3 : int GetOverviewCount() override
685 : {
686 3 : return (int)apoOverviews.size();
687 : }
688 :
689 : GDALRasterBand *GetOverview(int) override;
690 :
691 : GDALColorInterp GetColorInterpretation() override;
692 : CPLErr SetColorInterpretation(GDALColorInterp) override;
693 :
694 : CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
695 : int nBufXSize, int nBufYSize, GDALDataType eDT,
696 : char **papszOptions) override;
697 : #if ECWSDK_VERSION >= 50
698 : void GetBandIndexAndCountForStatistics(int &bandIndex,
699 : int &bandCount) const;
700 : CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax, int *pnBuckets,
701 : GUIntBig **ppanHistogram, int bForce,
702 : GDALProgressFunc, void *pProgressData) override;
703 : virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
704 : GUIntBig *panHistogram) override;
705 : double GetMinimum(int *pbSuccess) override;
706 : double GetMaximum(int *pbSuccess) override;
707 : virtual CPLErr GetStatistics(int bApproxOK, int bForce, double *pdfMin,
708 : double *pdfMax, double *pdfMean,
709 : double *padfStdDev) override;
710 : virtual CPLErr SetStatistics(double dfMin, double dfMax, double dfMean,
711 : double dfStdDev) override;
712 :
713 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
714 : const char *pszDomain = "") override;
715 : #endif
716 : };
717 :
718 : int ECWTranslateFromWKT(const OGRSpatialReference *poSRS, char *pszProjection,
719 : int nProjectionLen, char *pszDatum, int nDatumLen,
720 : char *pszUnits);
721 :
722 : CellSizeUnits ECWTranslateToCellSizeUnits(const char *pszUnits);
723 : const char *ECWTranslateFromCellSizeUnits(CellSizeUnits eUnits);
724 :
725 : #endif /* ndef GDAL_ECW_H_INCLUDED */
|