Coverage Report

Created: 2026-09-26 08:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
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
    int ExposeUnderlyingJPEGDatasetOverviews() const
123
14
    {
124
14
        return bExposeUnderlyingJPEGDatasetOverviews;
125
14
    }
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 &gt) const override;
156
    CPLErr SetGeoTransform(const GDALGeoTransform &gt) 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,
300
                                     CSLConstList papszOptions) override;
301
    /*virtual CPLErr SetStatistics( double dfMin, double dfMax,
302
                                double dfMean, double dfStdDev );*/
303
    CPLErr ComputeRasterMinMax(int, double *) override;
304
305
    int HasArbitraryOverviews() override;
306
    int GetOverviewCount() override;
307
    GDALRasterBand *GetOverview(int) override;
308
    GDALRasterBand *GetRasterSampleOverview(GUIntBig) override;
309
    virtual CPLErr BuildOverviews(const char *, int, const int *,
310
                                  GDALProgressFunc, void *,
311
                                  CSLConstList papszOptions) override;
312
313
    CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
314
                      int nBufXSize, int nBufYSize, GDALDataType eDT,
315
                      CSLConstList papszOptions) override;
316
317
    /*virtual CPLErr  GetHistogram( double dfMin, double dfMax,
318
                        int nBuckets, GUIntBig * panHistogram,
319
                        int bIncludeOutOfRange, int bApproxOK,
320
                        GDALProgressFunc, void *pProgressData );
321
322
    CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax,
323
                                        int *pnBuckets, GUIntBig **
324
    ppanHistogram, int bForce, GDALProgressFunc, void *pProgressData); virtual
325
    CPLErr SetDefaultHistogram( double dfMin, double dfMax, int nBuckets,
326
    GUIntBig *panHistogram );*/
327
328
    /*virtual const GDALRasterAttributeTable *GetDefaultRAT();
329
    virtual CPLErr SetDefaultRAT( const GDALRasterAttributeTable * );*/
330
331
    GDALRasterBand *GetMaskBand() override;
332
    int GetMaskFlags() override;
333
    CPLErr CreateMaskBand(int nFlags) override;
334
};
335
336
/************************************************************************/
337
/* ==================================================================== */
338
/*                       NITFWrapperRasterBand                          */
339
/* ==================================================================== */
340
/************************************************************************/
341
342
/* This class is used to wrap bands from JPEG or JPEG2000 datasets in */
343
/* bands of the NITF dataset. Previously a trick was applied in the */
344
/* relevant drivers to define a SetColorInterpretation() method and */
345
/* to make sure they keep the proper pointer to their "natural" dataset */
346
/* This trick is no longer necessary with the NITFWrapperRasterBand */
347
/* We just override the few specific methods where we want that */
348
/* the NITFWrapperRasterBand behavior differs from the JPEG/JPEG2000 one */
349
350
class NITFWrapperRasterBand final : public NITFProxyPamRasterBand
351
{
352
    GDALRasterBand *const poBaseBand;
353
    GDALColorTable *poColorTable = nullptr;
354
    GDALColorInterp eInterp = GCI_Undefined;
355
    const bool bIsJPEG;
356
357
    CPL_DISALLOW_COPY_ASSIGN(NITFWrapperRasterBand)
358
359
  protected:
360
    /* Pure virtual method of the NITFProxyPamRasterBand */
361
    GDALRasterBand *RefUnderlyingRasterBand() override;
362
363
  public:
364
    NITFWrapperRasterBand(NITFDataset *poDS, GDALRasterBand *poBaseBand,
365
                          int nBand);
366
    ~NITFWrapperRasterBand() override;
367
368
    /* Methods from GDALRasterBand we want to override */
369
    GDALColorInterp GetColorInterpretation() override;
370
    CPLErr SetColorInterpretation(GDALColorInterp) override;
371
372
    GDALColorTable *GetColorTable() override;
373
374
    int GetOverviewCount() override;
375
    GDALRasterBand *GetOverview(int) override;
376
377
    /* Specific method */
378
    void SetColorTableFromNITFBandInfo();
379
};
380
381
/************************************************************************/
382
/* ==================================================================== */
383
/*                        NITFComplexRasterBand                         */
384
/* ==================================================================== */
385
/************************************************************************/
386
387
/* This class is used to wrap 2 bands (I and Q) as a complex raster band */
388
class NITFComplexRasterBand final : public NITFRasterBand
389
{
390
    std::unique_ptr<NITFDataset> poIntermediateDS{};
391
    std::array<int, 2> anBandMap = {0, 0};
392
    GDALDataType underlyingDataType = GDT_Unknown;
393
    int complexDataTypeSize = 0;
394
    int underlyingDataTypeSize = 0;
395
396
  private:
397
    CPLErr IBlockIO(int nBlockXOff, int nBlockYOff, void *pImage,
398
                    GDALRWFlag rwFlag);
399
400
  public:
401
    NITFComplexRasterBand(NITFDataset *poDSIn, GDALRasterBand *poBandI,
402
                          GDALRasterBand *poBandQ, int nIBand, int nQBand);
403
404
    CPLErr IReadBlock(int, int, void *) override;
405
    CPLErr IWriteBlock(int, int, void *) override;
406
};
407
408
#endif /* NITF_DATASET_H_INCLUDED */