• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 14945877415

10 May 2025 01:37PM UTC coverage: 70.838% (+0.004%) from 70.834%
14945877415

Pull #12331

github

web-flow
Merge e74fde6a5 into a1ee70739
Pull Request #12331: GDALG: do not Open() in update mode, and 100% code coverage

12 of 12 new or added lines in 2 files covered. (100.0%)

73 existing lines in 35 files now uncovered.

565410 of 798178 relevant lines covered (70.84%)

234821.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

6.9
/frmts/airsar/airsardataset.cpp
1
/******************************************************************************
2
 *
3
 * Project:  AirSAR Reader
4
 * Purpose:  Implements read support for AirSAR Polarimetric data.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
9
 * Copyright (c) 2007-2009, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13

14
#include "cpl_conv.h"
15
#include "cpl_string.h"
16
#include "cpl_vsi.h"
17
#include "gdal_frmts.h"
18
#include "gdal_pam.h"
19

20
/************************************************************************/
21
/* ==================================================================== */
22
/*                              AirSARDataset                           */
23
/* ==================================================================== */
24
/************************************************************************/
25

26
class AirSARRasterBand;
27

28
class AirSARDataset final : public GDALPamDataset
29
{
30
    friend class AirSARRasterBand;
31

32
    VSILFILE *fp;
33

34
    int nLoadedLine;
35
    GByte *pabyCompressedLine;
36
    double *padfMatrix;
37

38
    int nDataStart;
39
    int nRecordLength;
40

41
    CPLErr LoadLine(int iLine);
42

43
    static char **ReadHeader(VSILFILE *fp, int nFileOffset,
44
                             const char *pszPrefix, int nMaxLines);
45

46
  public:
47
    AirSARDataset();
48
    ~AirSARDataset();
49

50
    static GDALDataset *Open(GDALOpenInfo *);
51
};
52

53
/************************************************************************/
54
/* ==================================================================== */
55
/*                            AirSARRasterBand                          */
56
/* ==================================================================== */
57
/************************************************************************/
58

59
class AirSARRasterBand final : public GDALPamRasterBand
60
{
61
  public:
62
    AirSARRasterBand(AirSARDataset *, int);
63
    ~AirSARRasterBand() override;
64

65
    CPLErr IReadBlock(int, int, void *) override;
66
};
67

68
/* locations of stokes matrix values within padfMatrix ... same order as they
69
   are computed in the document. */
70

71
constexpr int M11 = 0;
72
constexpr int M12 = 1;
73
constexpr int M13 = 2;
74
constexpr int M14 = 3;
75
constexpr int M23 = 4;
76
constexpr int M24 = 5;
77
constexpr int M33 = 6;
78
constexpr int M34 = 7;
79
constexpr int M44 = 8;
80
constexpr int M22 = 9;
81

82
/************************************************************************/
83
/*                          AirSARRasterBand()                          */
84
/************************************************************************/
85

86
AirSARRasterBand::AirSARRasterBand(AirSARDataset *poDSIn, int nBandIn)
×
87

88
{
89
    poDS = poDSIn;
×
90
    nBand = nBandIn;
×
91

92
    nBlockXSize = poDS->GetRasterXSize();
×
93
    nBlockYSize = 1;
×
94

95
    if (this->nBand == 2 || this->nBand == 3 || this->nBand == 5)
×
96
        eDataType = GDT_CFloat32;
×
97
    else
98
        eDataType = GDT_Float32;
×
99

100
    switch (nBand)
×
101
    {
102
        case 1:
×
103
            SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_11");
×
104
            SetDescription("Covariance_11");
×
105
            eDataType = GDT_CFloat32;
×
106
            break;
×
107

108
        case 2:
×
109
            SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_12");
×
110
            SetDescription("Covariance_12");
×
111
            eDataType = GDT_CFloat32;
×
112
            break;
×
113

114
        case 3:
×
115
            SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_13");
×
116
            SetDescription("Covariance_13");
×
117
            eDataType = GDT_CFloat32;
×
118
            break;
×
119

120
        case 4:
×
121
            SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_22");
×
122
            SetDescription("Covariance_22");
×
123
            eDataType = GDT_CFloat32;
×
124
            break;
×
125

126
        case 5:
×
127
            SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_23");
×
128
            SetDescription("Covariance_23");
×
129
            eDataType = GDT_CFloat32;
×
130
            break;
×
131

132
        case 6:
×
133
            SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_33");
×
134
            SetDescription("Covariance_33");
×
135
            eDataType = GDT_CFloat32;
×
136
            break;
×
137
    }
138
}
×
139

140
/************************************************************************/
141
/*                         ~AirSARRasterBand()                          */
142
/************************************************************************/
143

144
AirSARRasterBand::~AirSARRasterBand()
×
145

146
{
147
}
×
148

149
/************************************************************************/
150
/*                             IReadBlock()                             */
151
/************************************************************************/
152

153
CPLErr AirSARRasterBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff,
×
154
                                    void *pImage)
155
{
156
    float *pafLine = (float *)pImage;
×
157
    const double SQRT_2 = 1.4142135623730951;
×
158

159
    CPLErr eErr = ((AirSARDataset *)poDS)->LoadLine(nBlockYOff);
×
160
    if (eErr != CE_None)
×
161
        return eErr;
×
162

163
    double *padfMatrix = ((AirSARDataset *)poDS)->padfMatrix;
×
164

165
    if (nBand == 1) /* C11 */
×
166
    {
167
        for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
×
168
        {
169
            double *m = padfMatrix + 10 * iPixel;
×
170

171
            pafLine[iPixel * 2 + 0] = (float)(m[M11] + m[M22] + 2 * m[M12]);
×
172
            pafLine[iPixel * 2 + 1] = 0.0;
×
173
        }
174
    }
175
    else if (nBand == 2) /* C12 */
×
176
    {
177
        for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
×
178
        {
179
            double *m = padfMatrix + 10 * iPixel;
×
180

181
            // real
182
            pafLine[iPixel * 2 + 0] = (float)(SQRT_2 * (m[M13] + m[M23]));
×
183

184
            // imaginary
185
            pafLine[iPixel * 2 + 1] = (float)(-SQRT_2 * (m[M24] + m[M14]));
×
186
        }
187
    }
188
    else if (nBand == 3) /* C13 */
×
189
    {
190
        for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
×
191
        {
192
            double *m = padfMatrix + 10 * iPixel;
×
193

194
            // real
195
            pafLine[iPixel * 2 + 0] = (float)(2 * m[M33] + m[M22] - m[M11]);
×
196

197
            // imaginary
198
            pafLine[iPixel * 2 + 1] = (float)(-2 * m[M34]);
×
199
        }
200
    }
201
    else if (nBand == 4) /* C22 */
×
202
    {
203
        for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
×
204
        {
205
            double *m = padfMatrix + 10 * iPixel;
×
206

207
            pafLine[iPixel * 2 + 0] = (float)(2 * (m[M11] - m[M22]));
×
208
            pafLine[iPixel * 2 + 1] = 0.0;
×
209
        }
210
    }
211
    else if (nBand == 5) /* C23 */
×
212
    {
213
        for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
×
214
        {
215
            double *m = padfMatrix + 10 * iPixel;
×
216

217
            // real
218
            pafLine[iPixel * 2 + 0] = (float)(SQRT_2 * (m[M13] - m[M23]));
×
219

220
            // imaginary
221
            pafLine[iPixel * 2 + 1] = (float)(SQRT_2 * (m[M24] - m[M14]));
×
222
        }
223
    }
224
    else if (nBand == 6) /* C33 */
×
225
    {
226
        for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
×
227
        {
228
            double *m = padfMatrix + 10 * iPixel;
×
229

230
            pafLine[iPixel * 2 + 0] = (float)(m[M11] + m[M22] - 2 * m[M12]);
×
231
            pafLine[iPixel * 2 + 1] = 0.0;
×
232
        }
233
    }
234

235
    return CE_None;
×
236
}
237

238
/************************************************************************/
239
/* ==================================================================== */
240
/*                              AirSARDataset                           */
241
/* ==================================================================== */
242
/************************************************************************/
243

244
/************************************************************************/
245
/*                           AirSARDataset()                            */
246
/************************************************************************/
247

248
AirSARDataset::AirSARDataset()
×
249
    : fp(nullptr), nLoadedLine(-1), pabyCompressedLine(nullptr),
250
      padfMatrix(nullptr), nDataStart(0), nRecordLength(0)
×
251
{
252
}
×
253

254
/************************************************************************/
255
/*                           ~AirSARDataset()                           */
256
/************************************************************************/
257

258
AirSARDataset::~AirSARDataset()
×
259

260
{
261
    FlushCache(true);
×
262
    CPLFree(pabyCompressedLine);
×
263
    CPLFree(padfMatrix);
×
264

265
    if (fp != nullptr)
×
266
    {
267
        VSIFCloseL(fp);
×
268
        fp = nullptr;
×
269
    }
270
}
×
271

272
/************************************************************************/
273
/*                              LoadLine()                              */
274
/************************************************************************/
275

276
CPLErr AirSARDataset::LoadLine(int iLine)
×
277

278
{
279
    if (iLine == nLoadedLine)
×
280
        return CE_None;
×
281

282
    /* -------------------------------------------------------------------- */
283
    /*      allocate working buffers if we don't have them already.         */
284
    /* -------------------------------------------------------------------- */
285
    if (pabyCompressedLine == nullptr)
×
286
    {
287
        pabyCompressedLine = (GByte *)VSI_MALLOC2_VERBOSE(nRasterXSize, 10);
×
288

289
        padfMatrix =
×
290
            (double *)VSI_MALLOC2_VERBOSE(10 * sizeof(double), nRasterXSize);
×
291
        if (pabyCompressedLine == nullptr || padfMatrix == nullptr)
×
292
        {
293
            CPLFree(pabyCompressedLine);
×
294
            CPLFree(padfMatrix);
×
295
            return CE_Failure;
×
296
        }
297
    }
298

299
    CPLAssert(nRecordLength == nRasterXSize * 10);
×
300

301
    /* -------------------------------------------------------------------- */
302
    /*      Load raw compressed data.                                       */
303
    /* -------------------------------------------------------------------- */
304
    if (VSIFSeekL(fp, nDataStart + iLine * nRecordLength, SEEK_SET) != 0 ||
×
305
        ((int)VSIFReadL(pabyCompressedLine, 10, nRasterXSize, fp)) !=
×
306
            nRasterXSize)
×
307
    {
308
        CPLError(CE_Failure, CPLE_FileIO,
×
309
                 "Error reading %d bytes for line %d at offset %d.\n%s",
310
                 nRasterXSize * 10, iLine, nDataStart + iLine * nRecordLength,
×
311
                 VSIStrerror(errno));
×
312
        return CE_Failure;
×
313
    }
314

315
    /* -------------------------------------------------------------------- */
316
    /*      Build stokes matrix                                             */
317
    /* -------------------------------------------------------------------- */
318
    for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
×
319
    {
320
        double *M = padfMatrix + 10 * iPixel;
×
321
        signed char *byte = (signed char *)pabyCompressedLine + 10 * iPixel - 1;
×
322
        const double gen_fac = 1.0;  // should we have a general scale factor?
×
323

324
        M[M11] = (byte[2] / 254.0 + 1.5) * pow(2.0, byte[1]) * gen_fac;
×
325
        M[M12] = byte[3] * M[M11] / 127.0;
×
326
        M[M13] = byte[4] * fabs((double)byte[4]) * M[M11] / (127 * 127);
×
327
        M[M14] = byte[5] * fabs((double)byte[5]) * M[M11] / (127 * 127);
×
328
        M[M23] = byte[6] * fabs((double)byte[6]) * M[M11] / (127 * 127);
×
329
        M[M24] = byte[7] * fabs((double)byte[7]) * M[M11] / (127 * 127);
×
330
        M[M33] = byte[8] * M[M11] / 127;
×
331
        M[M34] = byte[9] * M[M11] / 127;
×
332
        M[M44] = byte[10] * M[M11] / 127;
×
333
        M[M22] = M[M11] - M[M33] - M[M44];
×
334
    }
335

336
    return CE_None;
×
337
}
338

339
/************************************************************************/
340
/*                             ReadHeader()                             */
341
/*                                                                      */
342
/*      Read the AirSAR header.  We assume an equal sign separates      */
343
/*      the keyword name from the value.  If not, assume the last       */
344
/*      "blank delimited" word is the value and everything else is a    */
345
/*      keyword.                                                        */
346
/*                                                                      */
347
/*      The records are 50 characters each.  Read till we get an all    */
348
/*      blank record or some zero bytes.                                */
349
/************************************************************************/
350

351
char **AirSARDataset::ReadHeader(VSILFILE *fp, int nFileOffset,
×
352
                                 const char *pszPrefix, int nMaxLines)
353

354
{
355
    char **papszHeadInfo = nullptr;
×
356
    char szLine[51];
357

358
    VSIFSeekL(fp, nFileOffset, SEEK_SET);
×
359

360
    /* ==================================================================== */
361
    /*      Loop collecting one line at a time.                             */
362
    /* ==================================================================== */
363
    for (int iLine = 0; iLine < nMaxLines; iLine++)
×
364
    {
365
        /* --------------------------------------------------------------------
366
         */
367
        /*      Read a 50 byte header record. */
368
        /* --------------------------------------------------------------------
369
         */
370
        if (VSIFReadL(szLine, 1, 50, fp) != 50)
×
371
        {
372
            CPLError(CE_Failure, CPLE_FileIO,
×
373
                     "Read error collecting AirSAR header.");
374
            CSLDestroy(papszHeadInfo);
×
375
            return nullptr;
×
376
        }
377

378
        szLine[50] = '\0';
×
379

380
        /* --------------------------------------------------------------------
381
         */
382
        /*      Is it all spaces, or does it have a zero byte? */
383
        /* --------------------------------------------------------------------
384
         */
385
        bool bAllSpaces = true;
×
386
        bool bHasIllegalChars = false;
×
387

388
        for (int i = 0; i < 50; i++)
×
389
        {
390
            if (szLine[i] == '\0')
×
391
                break;
×
392

393
            if (szLine[i] != ' ')
×
394
                bAllSpaces = false;
×
395

396
            if (((unsigned char *)szLine)[i] > 127 ||
×
397
                ((unsigned char *)szLine)[i] < 10)
×
398
                bHasIllegalChars = true;
×
399
        }
400

401
        if (bAllSpaces || bHasIllegalChars)
×
402
            break;
403

404
        /* --------------------------------------------------------------------
405
         */
406
        /*      Find the pivot between the keyword name and value. */
407
        /* --------------------------------------------------------------------
408
         */
409
        int iPivot = -1;
×
410

411
        for (int i = 0; i < 50; i++)
×
412
        {
413
            if (szLine[i] == '=')
×
414
            {
415
                iPivot = i;
×
416
                break;
×
417
            }
418
        }
419

420
        // If no "=" found, split on first double white space
421
        if (iPivot == -1)
×
422
        {
423
            for (int i = 48; i >= 0; i--)
×
424
            {
425
                if (szLine[i] == ' ' && szLine[i + 1] == ' ')
×
426
                {
427
                    iPivot = i;
×
428
                    break;
×
429
                }
430
            }
431
        }
432

433
        if (iPivot == -1)  // Yikes!
×
434
        {
435
            CPLDebug("AIRSAR", "No pivot in line `%s'.", szLine);
×
436
            CPLAssert(iPivot != -1);
×
437
            break;
×
438
        }
439

440
        /* --------------------------------------------------------------------
441
         */
442
        /*      Trace ahead to the first non-white space value character. */
443
        /* --------------------------------------------------------------------
444
         */
445
        int iValue = iPivot + 1;
×
446

447
        while (iValue < 50 && szLine[iValue] == ' ')
×
448
            iValue++;
×
449

450
        /* --------------------------------------------------------------------
451
         */
452
        /*      Strip any white space off the keyword. */
453
        /* --------------------------------------------------------------------
454
         */
455
        int iKeyEnd = iPivot - 1;
×
456

457
        while (iKeyEnd > 0 && szLine[iKeyEnd] == ' ')
×
458
            iKeyEnd--;
×
459

460
        szLine[iKeyEnd + 1] = '\0';
×
461

462
        /* --------------------------------------------------------------------
463
         */
464
        /*      Convert spaces or colons into underscores in the key name. */
465
        /* --------------------------------------------------------------------
466
         */
467
        for (int i = 0; szLine[i] != '\0'; i++)
×
468
        {
469
            if (szLine[i] == ' ' || szLine[i] == ':' || szLine[i] == ',')
×
470
                szLine[i] = '_';
×
471
        }
472

473
        /* --------------------------------------------------------------------
474
         */
475
        /*      Prefix key name with provided prefix string. */
476
        /* --------------------------------------------------------------------
477
         */
478
        char szPrefixedKeyName[55];
479

480
        snprintf(szPrefixedKeyName, sizeof(szPrefixedKeyName), "%s_%s",
×
481
                 pszPrefix, szLine);
482

483
        papszHeadInfo =
484
            CSLSetNameValue(papszHeadInfo, szPrefixedKeyName, szLine + iValue);
×
485
    }
486

487
    return papszHeadInfo;
×
488
}
489

490
/************************************************************************/
491
/*                                Open()                                */
492
/************************************************************************/
493

494
GDALDataset *AirSARDataset::Open(GDALOpenInfo *poOpenInfo)
34,332✔
495

496
{
497
    if (poOpenInfo->fpL == nullptr || poOpenInfo->nHeaderBytes < 800)
34,332✔
498
        return nullptr;
30,300✔
499

500
    /* -------------------------------------------------------------------- */
501
    /*      Check for AirSAR/ keyword.                                      */
502
    /* -------------------------------------------------------------------- */
503
    if (!STARTS_WITH_CI((char *)poOpenInfo->pabyHeader,
4,032✔
504
                        "RECORD LENGTH IN BYTES"))
505
        return nullptr;
4,032✔
506

UNCOV
507
    if (strstr((char *)poOpenInfo->pabyHeader, "COMPRESSED") == nullptr ||
×
508
        strstr((char *)poOpenInfo->pabyHeader, "JPL AIRCRAFT") == nullptr)
×
UNCOV
509
        return nullptr;
×
510

511
    /* -------------------------------------------------------------------- */
512
    /*      Parse the header fields.  We turn all the transform the         */
513
    /*      keywords by converting spaces to underscores so they will be    */
514
    /*      "well behaved" as metadata keywords.                            */
515
    /* -------------------------------------------------------------------- */
516
    char **papszMD = ReadHeader(poOpenInfo->fpL, 0, "MH", 20);
×
517

518
    if (papszMD == nullptr)
×
519
        return nullptr;
×
520

521
    /* -------------------------------------------------------------------- */
522
    /*      Confirm the requested access is supported.                      */
523
    /* -------------------------------------------------------------------- */
524
    if (poOpenInfo->eAccess == GA_Update)
×
525
    {
526
        ReportUpdateNotSupportedByDriver("AIRSAR");
×
527
        CSLDestroy(papszMD);
×
528
        return nullptr;
×
529
    }
530
    /* -------------------------------------------------------------------- */
531
    /*      Create a corresponding GDALDataset.                             */
532
    /* -------------------------------------------------------------------- */
533
    AirSARDataset *poDS = new AirSARDataset();
×
534

535
    /* -------------------------------------------------------------------- */
536
    /*      Extract some key information.                                   */
537
    /* -------------------------------------------------------------------- */
538

539
    poDS->nRasterXSize =
×
540
        atoi(CSLFetchNameValue(papszMD, "MH_NUMBER_OF_SAMPLES_PER_RECORD"));
×
541
    poDS->nRasterYSize =
×
542
        atoi(CSLFetchNameValue(papszMD, "MH_NUMBER_OF_LINES_IN_IMAGE"));
×
543

544
    poDS->nRecordLength =
×
545
        atoi(CSLFetchNameValue(papszMD, "MH_RECORD_LENGTH_IN_BYTES"));
×
546

547
    poDS->nDataStart =
×
548
        atoi(CSLFetchNameValue(papszMD, "MH_BYTE_OFFSET_OF_FIRST_DATA_RECORD"));
×
549

550
    /* -------------------------------------------------------------------- */
551
    /*      Adopt the openinfo file pointer.                                */
552
    /* -------------------------------------------------------------------- */
553
    poDS->fp = poOpenInfo->fpL;
×
554
    poOpenInfo->fpL = nullptr;
×
555

556
    /* -------------------------------------------------------------------- */
557
    /*      Read and merge parameter header into metadata.  Prefix          */
558
    /*      parameter header values with PH_.                               */
559
    /* -------------------------------------------------------------------- */
560
    int nPHOffset = 0;
×
561

562
    if (CSLFetchNameValue(papszMD, "MH_BYTE_OFFSET_OF_PARAMETER_HEADER") !=
×
563
        nullptr)
564
    {
565
        nPHOffset = atoi(
×
566
            CSLFetchNameValue(papszMD, "MH_BYTE_OFFSET_OF_PARAMETER_HEADER"));
567
        char **papszPHInfo = ReadHeader(poDS->fp, nPHOffset, "PH", 100);
×
568

569
        papszMD = CSLInsertStrings(papszMD, CSLCount(papszMD), papszPHInfo);
×
570

571
        CSLDestroy(papszPHInfo);
×
572
    }
573

574
    /* -------------------------------------------------------------------- */
575
    /*      Read and merge calibration header into metadata.  Prefix        */
576
    /*      parameter header values with CH_.                               */
577
    /* -------------------------------------------------------------------- */
578
    if (nPHOffset != 0)
×
579
    {
580
        char **papszCHInfo =
581
            ReadHeader(poDS->fp, nPHOffset + poDS->nRecordLength, "CH", 18);
×
582

583
        papszMD = CSLInsertStrings(papszMD, CSLCount(papszMD), papszCHInfo);
×
584

585
        CSLDestroy(papszCHInfo);
×
586
    }
587

588
    /* -------------------------------------------------------------------- */
589
    /*      Assign metadata to dataset.                                     */
590
    /* -------------------------------------------------------------------- */
591
    poDS->SetMetadata(papszMD);
×
592
    CSLDestroy(papszMD);
×
593

594
    /* -------------------------------------------------------------------- */
595
    /*      Create band information objects.                                */
596
    /* -------------------------------------------------------------------- */
597
    poDS->SetBand(1, new AirSARRasterBand(poDS, 1));
×
598
    poDS->SetBand(2, new AirSARRasterBand(poDS, 2));
×
599
    poDS->SetBand(3, new AirSARRasterBand(poDS, 3));
×
600
    poDS->SetBand(4, new AirSARRasterBand(poDS, 4));
×
601
    poDS->SetBand(5, new AirSARRasterBand(poDS, 5));
×
602
    poDS->SetBand(6, new AirSARRasterBand(poDS, 6));
×
603

604
    poDS->SetMetadataItem("MATRIX_REPRESENTATION", "SYMMETRIZED_COVARIANCE");
×
605

606
    /* -------------------------------------------------------------------- */
607
    /*      Initialize any PAM information.                                 */
608
    /* -------------------------------------------------------------------- */
609
    poDS->SetDescription(poOpenInfo->pszFilename);
×
610
    poDS->TryLoadXML();
×
611

612
    poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename);
×
613

614
    return poDS;
×
615
}
616

617
/************************************************************************/
618
/*                        GDALRegister_AirSAR()                         */
619
/************************************************************************/
620

621
void GDALRegister_AirSAR()
1,672✔
622

623
{
624
    if (GDALGetDriverByName("AirSAR") != nullptr)
1,672✔
625
        return;
282✔
626

627
    GDALDriver *poDriver = new GDALDriver();
1,390✔
628

629
    poDriver->SetDescription("AirSAR");
1,390✔
630
    poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
1,390✔
631
    poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "AirSAR Polarimetric Image");
1,390✔
632
    poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/airsar.html");
1,390✔
633

634
    poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
1,390✔
635

636
    poDriver->pfnOpen = AirSARDataset::Open;
1,390✔
637

638
    GetGDALDriverManager()->RegisterDriver(poDriver);
1,390✔
639
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc