Coverage Report

Created: 2025-11-15 08:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/ceos/ceosdataset.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  CEOS Translator
4
 * Purpose:  GDALDataset driver for CEOS translator.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 1999, Frank Warmerdam
9
 * Copyright (c) 2009-2010, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#include "ceosopen.h"
15
#include "gdal_frmts.h"
16
#include "gdal_pam.h"
17
#include "gdal_driver.h"
18
#include "gdal_drivermanager.h"
19
#include "gdal_openinfo.h"
20
#include "gdal_cpp_functions.h"
21
22
/************************************************************************/
23
/* ==================================================================== */
24
/*                              CEOSDataset                             */
25
/* ==================================================================== */
26
/************************************************************************/
27
28
class CEOSRasterBand;
29
30
class CEOSDataset final : public GDALPamDataset
31
{
32
    friend class CEOSRasterBand;
33
34
    CEOSImage *psCEOS;
35
36
    CPL_DISALLOW_COPY_ASSIGN(CEOSDataset)
37
38
  public:
39
    CEOSDataset();
40
    ~CEOSDataset() override;
41
    static GDALDataset *Open(GDALOpenInfo *);
42
};
43
44
/************************************************************************/
45
/* ==================================================================== */
46
/*                            CEOSRasterBand                             */
47
/* ==================================================================== */
48
/************************************************************************/
49
50
class CEOSRasterBand final : public GDALPamRasterBand
51
{
52
    friend class CEOSDataset;
53
54
  public:
55
    CEOSRasterBand(CEOSDataset *, int);
56
57
    CPLErr IReadBlock(int, int, void *) override;
58
};
59
60
/************************************************************************/
61
/*                           CEOSRasterBand()                            */
62
/************************************************************************/
63
64
CEOSRasterBand::CEOSRasterBand(CEOSDataset *poDSIn, int nBandIn)
65
66
38
{
67
38
    poDS = poDSIn;
68
38
    nBand = nBandIn;
69
70
38
    eDataType = GDT_Byte;
71
72
38
    nBlockXSize = poDS->GetRasterXSize();
73
38
    nBlockYSize = 1;
74
38
}
75
76
/************************************************************************/
77
/*                             IReadBlock()                             */
78
/************************************************************************/
79
80
CPLErr CEOSRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff, int nBlockYOff,
81
                                  void *pImage)
82
154
{
83
154
    CEOSDataset *poCEOS_DS = cpl::down_cast<CEOSDataset *>(poDS);
84
85
154
    CPLAssert(nBlockXOff == 0);
86
87
154
    return CEOSReadScanline(poCEOS_DS->psCEOS, nBand, nBlockYOff + 1, pImage);
88
154
}
89
90
/************************************************************************/
91
/* ==================================================================== */
92
/*                             CEOSDataset                              */
93
/* ==================================================================== */
94
/************************************************************************/
95
96
/************************************************************************/
97
/*                            CEOSDataset()                             */
98
/************************************************************************/
99
100
11
CEOSDataset::CEOSDataset() : psCEOS(nullptr)
101
11
{
102
11
}
103
104
/************************************************************************/
105
/*                            ~CEOSDataset()                            */
106
/************************************************************************/
107
108
CEOSDataset::~CEOSDataset()
109
110
11
{
111
11
    FlushCache(true);
112
11
    if (psCEOS)
113
11
        CEOSClose(psCEOS);
114
11
}
115
116
/************************************************************************/
117
/*                                Open()                                */
118
/************************************************************************/
119
120
GDALDataset *CEOSDataset::Open(GDALOpenInfo *poOpenInfo)
121
122
659k
{
123
    /* -------------------------------------------------------------------- */
124
    /*      Before trying CEOSOpen() we first verify that the first         */
125
    /*      record is in fact a CEOS file descriptor record.                */
126
    /* -------------------------------------------------------------------- */
127
659k
    if (poOpenInfo->nHeaderBytes < 100)
128
576k
        return nullptr;
129
130
83.2k
    if (poOpenInfo->pabyHeader[4] != 0x3f ||
131
83
        poOpenInfo->pabyHeader[5] != 0xc0 ||
132
31
        poOpenInfo->pabyHeader[6] != 0x12 || poOpenInfo->pabyHeader[7] != 0x12)
133
83.2k
        return nullptr;
134
135
    /* -------------------------------------------------------------------- */
136
    /*      Try opening the dataset.                                        */
137
    /* -------------------------------------------------------------------- */
138
30
    CEOSImage *psCEOS = CEOSOpen(poOpenInfo->pszFilename, "rb");
139
30
    if (psCEOS == nullptr)
140
17
        return nullptr;
141
142
13
    if (psCEOS->nBitsPerPixel != 8)
143
1
    {
144
1
        CPLError(CE_Failure, CPLE_NotSupported,
145
1
                 "The CEOS driver cannot handle nBitsPerPixel = %d",
146
1
                 psCEOS->nBitsPerPixel);
147
1
        CEOSClose(psCEOS);
148
1
        return nullptr;
149
1
    }
150
151
12
    if (!GDALCheckDatasetDimensions(psCEOS->nPixels, psCEOS->nBands) ||
152
11
        !GDALCheckBandCount(psCEOS->nBands, FALSE))
153
1
    {
154
1
        CEOSClose(psCEOS);
155
1
        return nullptr;
156
1
    }
157
158
    /* -------------------------------------------------------------------- */
159
    /*      Confirm the requested access is supported.                      */
160
    /* -------------------------------------------------------------------- */
161
11
    if (poOpenInfo->eAccess == GA_Update)
162
0
    {
163
0
        CEOSClose(psCEOS);
164
0
        ReportUpdateNotSupportedByDriver("CEOS");
165
0
        return nullptr;
166
0
    }
167
    /* -------------------------------------------------------------------- */
168
    /*      Create a corresponding GDALDataset.                             */
169
    /* -------------------------------------------------------------------- */
170
11
    CEOSDataset *poDS = new CEOSDataset();
171
172
11
    poDS->psCEOS = psCEOS;
173
174
    /* -------------------------------------------------------------------- */
175
    /*      Capture some information from the file that is of interest.     */
176
    /* -------------------------------------------------------------------- */
177
11
    poDS->nRasterXSize = psCEOS->nPixels;
178
11
    poDS->nRasterYSize = psCEOS->nLines;
179
180
    /* -------------------------------------------------------------------- */
181
    /*      Create band information objects.                                */
182
    /* -------------------------------------------------------------------- */
183
11
    poDS->nBands = psCEOS->nBands;
184
185
49
    for (int i = 0; i < poDS->nBands; i++)
186
38
        poDS->SetBand(i + 1, new CEOSRasterBand(poDS, i + 1));
187
188
    /* -------------------------------------------------------------------- */
189
    /*      Initialize any PAM information.                                 */
190
    /* -------------------------------------------------------------------- */
191
11
    poDS->SetDescription(poOpenInfo->pszFilename);
192
11
    poDS->TryLoadXML();
193
194
    /* -------------------------------------------------------------------- */
195
    /*      Check for overviews.                                            */
196
    /* -------------------------------------------------------------------- */
197
11
    poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename);
198
199
11
    return poDS;
200
11
}
201
202
/************************************************************************/
203
/*                          GDALRegister_GTiff()                        */
204
/************************************************************************/
205
206
void GDALRegister_CEOS()
207
208
22
{
209
22
    if (GDALGetDriverByName("CEOS") != nullptr)
210
0
        return;
211
212
22
    GDALDriver *poDriver = new GDALDriver();
213
214
22
    poDriver->SetDescription("CEOS");
215
22
    poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
216
22
    poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "CEOS Image");
217
22
    poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/ceos.html");
218
22
    poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
219
220
22
    poDriver->pfnOpen = CEOSDataset::Open;
221
222
22
    GetGDALDriverManager()->RegisterDriver(poDriver);
223
22
}