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