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