/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 | } |