Coverage Report

Created: 2025-07-23 09:13

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