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