Coverage Report

Created: 2025-08-11 09:23

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