Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: NITF Read/Write Translator
4 : * Purpose: GDALDataset/GDALRasterBand declarations.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2002, Frank Warmerdam
9 : * Copyright (c) 2011-2013, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * Portions Copyright (c) Her majesty the Queen in right of Canada as
12 : * represented by the Minister of National Defence, 2006.
13 : *
14 : * SPDX-License-Identifier: MIT
15 : ****************************************************************************/
16 :
17 : #ifndef NITF_DATASET_H_INCLUDED
18 : #define NITF_DATASET_H_INCLUDED
19 :
20 : #include "gdal_pam.h"
21 : #include "nitflib.h"
22 : #include "ogr_spatialref.h"
23 : #include "gdal_proxy.h"
24 :
25 : #include <array>
26 : #include <map>
27 :
28 : struct CADRGCreateCopyContext;
29 :
30 : CPLErr NITFSetColorInterpretation(NITFImage *psImage, int nBand,
31 : GDALColorInterp eInterp);
32 :
33 : /* Unused in normal builds. Caller code in nitfdataset.cpp is protected by
34 : * #ifdef ESRI_BUILD */
35 : #ifdef ESRI_BUILD
36 : /* -------------------------------------------------------------------- */
37 : /* Functions in nitf_gcprpc.cpp. */
38 : /* -------------------------------------------------------------------- */
39 :
40 : void NITFDensifyGCPs(GDAL_GCP **psGCPs, int *pnGCPCount);
41 : void NITFUpdateGCPsWithRPC(NITFRPC00BInfo *psRPCInfo, GDAL_GCP *psGCPs,
42 : int *pnGCPCount);
43 : #endif
44 :
45 : /************************************************************************/
46 : /* ==================================================================== */
47 : /* NITFDataset */
48 : /* ==================================================================== */
49 : /************************************************************************/
50 :
51 : class NITFRasterBand;
52 : class NITFWrapperRasterBand;
53 :
54 : class NITFDataset final : public GDALPamDataset
55 : {
56 : friend class NITFRasterBand;
57 : friend class NITFWrapperRasterBand;
58 : friend class NITFComplexRasterBand;
59 :
60 : NITFFile *psFile = nullptr;
61 : NITFImage *psImage = nullptr;
62 :
63 : std::unique_ptr<GDALDataset> poJ2KDataset{};
64 : int bJP2Writing = false;
65 : vsi_l_offset m_nImageOffset = 0;
66 : int m_nIMIndex = 0;
67 : int m_nImageCount = 0;
68 : vsi_l_offset m_nICOffset = 0;
69 : bool m_bHasComplexRasterBand = false;
70 :
71 : std::unique_ptr<GDALDataset> poJPEGDataset{};
72 :
73 : int bGotGeoTransform = false;
74 : GDALGeoTransform m_gt{};
75 :
76 : OGRSpatialReference m_oSRS{};
77 :
78 : int nGCPCount = 0;
79 : GDAL_GCP *pasGCPList = nullptr;
80 : OGRSpatialReference m_oGCPSRS{};
81 :
82 : GDALMultiDomainMetadata oSpecialMD{};
83 :
84 : #ifdef ESRI_BUILD
85 : void InitializeNITFDESMetadata();
86 : void InitializeNITFTREs();
87 : #endif
88 : bool InitializeNITFDESs(bool bValidate);
89 : void InitializeNITFMetadata();
90 : void InitializeCGMMetadata();
91 : void InitializeTextMetadata();
92 : bool InitializeTREMetadata(bool bValidate);
93 : void InitializeImageStructureMetadata();
94 :
95 : vsi_l_offset *panJPEGBlockOffset = nullptr;
96 : GByte *pabyJPEGBlock = nullptr;
97 : int nQLevel = 0;
98 :
99 : int ScanJPEGQLevel(GUIntBig *pnDataStart, bool *pbError);
100 : CPLErr ScanJPEGBlocks();
101 : CPLErr ReadJPEGBlock(int, int);
102 : void CheckGeoSDEInfo();
103 : char **AddFile(char **papszFileList, const char *EXTENSION,
104 : const char *extension);
105 :
106 : int nIMIndex = 0;
107 : CPLString osNITFFilename{};
108 :
109 : CPLString osRSetVRT{};
110 : int CheckForRSets(const char *pszFilename, char **papszSiblingFiles);
111 :
112 : char **papszTextMDToWrite = nullptr;
113 : char **papszCgmMDToWrite = nullptr;
114 : CPLStringList aosCreationOptions{};
115 :
116 : int bInLoadXML = false;
117 :
118 : CPLString m_osRPCTXTFilename{};
119 :
120 : int bExposeUnderlyingJPEGDatasetOverviews = false;
121 :
122 3 : int ExposeUnderlyingJPEGDatasetOverviews() const
123 : {
124 3 : return bExposeUnderlyingJPEGDatasetOverviews;
125 : }
126 :
127 : bool Validate();
128 :
129 : CPLErr Close(int &bHasDroppedRef);
130 :
131 : CPL_DISALLOW_COPY_ASSIGN(NITFDataset)
132 :
133 : protected:
134 : int CloseDependentDatasets() override;
135 :
136 : public:
137 : NITFDataset();
138 : ~NITFDataset() override;
139 :
140 : CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override;
141 :
142 : CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
143 : int nBufXSize, int nBufYSize, GDALDataType eDT,
144 : int nBandCount, int *panBandList,
145 : CSLConstList papszOptions) override;
146 :
147 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
148 : GDALDataType, int, BANDMAP_TYPE, GSpacing nPixelSpace,
149 : GSpacing nLineSpace, GSpacing nBandSpace,
150 : GDALRasterIOExtraArg *psExtraArg) override;
151 :
152 : const OGRSpatialReference *GetSpatialRef() const override;
153 : CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
154 :
155 : CPLErr GetGeoTransform(GDALGeoTransform >) const override;
156 : CPLErr SetGeoTransform(const GDALGeoTransform >) override;
157 : CPLErr SetGCPs(int nGCPCountIn, const GDAL_GCP *pasGCPListIn,
158 : const OGRSpatialReference *poSRS) override;
159 :
160 : int GetGCPCount() override;
161 : const OGRSpatialReference *GetGCPSpatialRef() const override;
162 : const GDAL_GCP *GetGCPs() override;
163 : char **GetFileList() override;
164 :
165 : char **GetMetadataDomainList() override;
166 : CSLConstList GetMetadata(const char *pszDomain = "") override;
167 : virtual const char *GetMetadataItem(const char *pszName,
168 : const char *pszDomain = "") override;
169 : CPLErr FlushCache(bool bAtClosing) override;
170 : CPLErr IBuildOverviews(const char *, int, const int *, int, const int *,
171 : GDALProgressFunc, void *,
172 : CSLConstList papszOptions) override;
173 :
174 : static NITFDataset *OpenInternal(GDALOpenInfo *,
175 : GDALDataset *poWritableJ2KDataset,
176 : bool bOpenForCreate, int nIMIndex);
177 : static GDALDataset *Open(GDALOpenInfo *);
178 : static GDALDataset *NITFCreateCopy(const char *pszFilename,
179 : GDALDataset *poSrcDS, int bStrict,
180 : CSLConstList papszOptions,
181 : GDALProgressFunc pfnProgress,
182 : void *pProgressData);
183 : static std::unique_ptr<GDALDataset>
184 : CreateCopy(const char *pszFilename, GDALDataset *poSrcDS, int bStrict,
185 : CSLConstList papszOptions, GDALProgressFunc pfnProgress,
186 : void *pProgressData, int nRecLevel,
187 : CADRGCreateCopyContext *copyContext);
188 : static GDALDataset *NITFDatasetCreate(const char *pszFilename, int nXSize,
189 : int nYSize, int nBands,
190 : GDALDataType eType,
191 : CSLConstList papszOptions);
192 : };
193 :
194 : /************************************************************************/
195 : /* ==================================================================== */
196 : /* NITFRasterBand */
197 : /* ==================================================================== */
198 : /************************************************************************/
199 :
200 : class NITFRasterBand CPL_NON_FINAL : public GDALPamRasterBand
201 : {
202 : friend class NITFDataset;
203 :
204 : NITFImage *psImage = nullptr;
205 :
206 : GDALColorTable *poColorTable = nullptr;
207 :
208 : GByte *pUnpackData = nullptr;
209 :
210 : int bScanlineAccess = false;
211 :
212 : CPL_DISALLOW_COPY_ASSIGN(NITFRasterBand)
213 :
214 : public:
215 : NITFRasterBand(NITFDataset *, int);
216 : ~NITFRasterBand() override;
217 :
218 : CPLErr IReadBlock(int, int, void *) override;
219 : CPLErr IWriteBlock(int, int, void *) override;
220 :
221 : GDALColorInterp GetColorInterpretation() override;
222 : CPLErr SetColorInterpretation(GDALColorInterp) override;
223 : GDALColorTable *GetColorTable() override;
224 : CPLErr SetColorTable(GDALColorTable *) override;
225 : double GetNoDataValue(int *pbSuccess = nullptr) override;
226 :
227 : void Unpack(GByte *pData);
228 : };
229 :
230 : /************************************************************************/
231 : /* ==================================================================== */
232 : /* NITFProxyPamRasterBand */
233 : /* ==================================================================== */
234 : /************************************************************************/
235 :
236 : /* This class is potentially of general interest and could be moved to
237 : * gdal_proxy.h */
238 : /* We don't proxy all methods. Generally speaking, the getters go to PAM first
239 : * and */
240 : /* then to the underlying band if no value exist in PAM. The setters aren't */
241 : /* overridden, so they go to PAM */
242 :
243 : class NITFProxyPamRasterBand CPL_NON_FINAL : public GDALPamRasterBand
244 : {
245 : private:
246 : std::map<CPLString, char **> oMDMap{};
247 :
248 : protected:
249 : virtual GDALRasterBand *RefUnderlyingRasterBand() = 0;
250 : virtual void
251 : UnrefUnderlyingRasterBand(GDALRasterBand *poUnderlyingRasterBand);
252 :
253 : CPLErr IReadBlock(int, int, void *) override;
254 : CPLErr IWriteBlock(int, int, void *) override;
255 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
256 : GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace,
257 : GDALRasterIOExtraArg *psExtraArg) override;
258 :
259 : public:
260 : ~NITFProxyPamRasterBand() override;
261 :
262 : CSLConstList GetMetadata(const char *pszDomain = "") override;
263 : /*virtual CPLErr SetMetadata( char ** papszMetadata,
264 : const char * pszDomain = "" );*/
265 : virtual const char *GetMetadataItem(const char *pszName,
266 : const char *pszDomain = "") override;
267 : /*virtual CPLErr SetMetadataItem( const char * pszName,
268 : const char * pszValue,
269 : const char * pszDomain = "" );*/
270 : CPLErr FlushCache(bool bAtClosing) override;
271 : /*virtual char **GetCategoryNames();*/
272 : double GetNoDataValue(int *pbSuccess = nullptr) override;
273 : double GetMinimum(int *pbSuccess = nullptr) override;
274 : double GetMaximum(int *pbSuccess = nullptr) override;
275 : /*virtual double GetOffset( int *pbSuccess = NULL );
276 : virtual double GetScale( int *pbSuccess = NULL );*/
277 : /*virtual const char *GetUnitType();*/
278 : GDALColorInterp GetColorInterpretation() override;
279 : GDALColorTable *GetColorTable() override;
280 : virtual CPLErr Fill(double dfRealValue,
281 : double dfImaginaryValue = 0) override;
282 :
283 : /*
284 : virtual CPLErr SetCategoryNames( char ** );
285 : virtual CPLErr SetNoDataValue( double );
286 : virtual CPLErr SetColorTable( GDALColorTable * );
287 : virtual CPLErr SetColorInterpretation( GDALColorInterp );
288 : virtual CPLErr SetOffset( double );
289 : virtual CPLErr SetScale( double );
290 : virtual CPLErr SetUnitType( const char * );
291 : */
292 :
293 : virtual CPLErr GetStatistics(int bApproxOK, int bForce, double *pdfMin,
294 : double *pdfMax, double *pdfMean,
295 : double *padfStdDev) override;
296 : virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
297 : double *pdfMax, double *pdfMean,
298 : double *pdfStdDev, GDALProgressFunc,
299 : void *pProgressData) override;
300 : /*virtual CPLErr SetStatistics( double dfMin, double dfMax,
301 : double dfMean, double dfStdDev );*/
302 : CPLErr ComputeRasterMinMax(int, double *) override;
303 :
304 : int HasArbitraryOverviews() override;
305 : int GetOverviewCount() override;
306 : GDALRasterBand *GetOverview(int) override;
307 : GDALRasterBand *GetRasterSampleOverview(GUIntBig) override;
308 : virtual CPLErr BuildOverviews(const char *, int, const int *,
309 : GDALProgressFunc, void *,
310 : CSLConstList papszOptions) override;
311 :
312 : CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
313 : int nBufXSize, int nBufYSize, GDALDataType eDT,
314 : CSLConstList papszOptions) override;
315 :
316 : /*virtual CPLErr GetHistogram( double dfMin, double dfMax,
317 : int nBuckets, GUIntBig * panHistogram,
318 : int bIncludeOutOfRange, int bApproxOK,
319 : GDALProgressFunc, void *pProgressData );
320 :
321 : CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax,
322 : int *pnBuckets, GUIntBig **
323 : ppanHistogram, int bForce, GDALProgressFunc, void *pProgressData); virtual
324 : CPLErr SetDefaultHistogram( double dfMin, double dfMax, int nBuckets,
325 : GUIntBig *panHistogram );*/
326 :
327 : /*virtual const GDALRasterAttributeTable *GetDefaultRAT();
328 : virtual CPLErr SetDefaultRAT( const GDALRasterAttributeTable * );*/
329 :
330 : GDALRasterBand *GetMaskBand() override;
331 : int GetMaskFlags() override;
332 : CPLErr CreateMaskBand(int nFlags) override;
333 : };
334 :
335 : /************************************************************************/
336 : /* ==================================================================== */
337 : /* NITFWrapperRasterBand */
338 : /* ==================================================================== */
339 : /************************************************************************/
340 :
341 : /* This class is used to wrap bands from JPEG or JPEG2000 datasets in */
342 : /* bands of the NITF dataset. Previously a trick was applied in the */
343 : /* relevant drivers to define a SetColorInterpretation() method and */
344 : /* to make sure they keep the proper pointer to their "natural" dataset */
345 : /* This trick is no longer necessary with the NITFWrapperRasterBand */
346 : /* We just override the few specific methods where we want that */
347 : /* the NITFWrapperRasterBand behavior differs from the JPEG/JPEG2000 one */
348 :
349 : class NITFWrapperRasterBand final : public NITFProxyPamRasterBand
350 : {
351 : GDALRasterBand *const poBaseBand;
352 : GDALColorTable *poColorTable = nullptr;
353 : GDALColorInterp eInterp = GCI_Undefined;
354 : const bool bIsJPEG;
355 :
356 : CPL_DISALLOW_COPY_ASSIGN(NITFWrapperRasterBand)
357 :
358 : protected:
359 : /* Pure virtual method of the NITFProxyPamRasterBand */
360 : GDALRasterBand *RefUnderlyingRasterBand() override;
361 :
362 : public:
363 : NITFWrapperRasterBand(NITFDataset *poDS, GDALRasterBand *poBaseBand,
364 : int nBand);
365 : ~NITFWrapperRasterBand() override;
366 :
367 : /* Methods from GDALRasterBand we want to override */
368 : GDALColorInterp GetColorInterpretation() override;
369 : CPLErr SetColorInterpretation(GDALColorInterp) override;
370 :
371 : GDALColorTable *GetColorTable() override;
372 :
373 : int GetOverviewCount() override;
374 : GDALRasterBand *GetOverview(int) override;
375 :
376 : /* Specific method */
377 : void SetColorTableFromNITFBandInfo();
378 : };
379 :
380 : /************************************************************************/
381 : /* ==================================================================== */
382 : /* NITFComplexRasterBand */
383 : /* ==================================================================== */
384 : /************************************************************************/
385 :
386 : /* This class is used to wrap 2 bands (I and Q) as a complex raster band */
387 : class NITFComplexRasterBand final : public NITFRasterBand
388 : {
389 : std::unique_ptr<NITFDataset> poIntermediateDS{};
390 : std::array<int, 2> anBandMap = {0, 0};
391 : GDALDataType underlyingDataType = GDT_Unknown;
392 : int complexDataTypeSize = 0;
393 : int underlyingDataTypeSize = 0;
394 :
395 : private:
396 : CPLErr IBlockIO(int nBlockXOff, int nBlockYOff, void *pImage,
397 : GDALRWFlag rwFlag);
398 :
399 : public:
400 : NITFComplexRasterBand(NITFDataset *poDSIn, GDALRasterBand *poBandI,
401 : GDALRasterBand *poBandQ, int nIBand, int nQBand);
402 :
403 : CPLErr IReadBlock(int, int, void *) override;
404 : CPLErr IWriteBlock(int, int, void *) override;
405 : };
406 :
407 : #endif /* NITF_DATASET_H_INCLUDED */
|