Coverage Report

Created: 2025-06-09 07:07

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