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 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 ****************************************************************************/
29
30 #include "ceosopen.h"
31 #include "gdal_frmts.h"
32 #include "gdal_pam.h"
33
34 CPL_CVSID("$Id: ceosdataset.cpp f6099e5ed704166bf5cc113a053dd1b2725cb391 2020-03-22 11:20:10 +0100 Kai Pastor $")
35
36 /************************************************************************/
37 /* ==================================================================== */
38 /* CEOSDataset */
39 /* ==================================================================== */
40 /************************************************************************/
41
42 class CEOSRasterBand;
43
44 class CEOSDataset final: public GDALPamDataset
45 {
46 friend class CEOSRasterBand;
47
48 CEOSImage *psCEOS;
49
50 public:
51 CEOSDataset();
52 ~CEOSDataset();
53 static GDALDataset *Open( GDALOpenInfo * );
54 };
55
56 /************************************************************************/
57 /* ==================================================================== */
58 /* CEOSRasterBand */
59 /* ==================================================================== */
60 /************************************************************************/
61
62 class CEOSRasterBand final: public GDALPamRasterBand
63 {
64 friend class CEOSDataset;
65
66 public:
67 CEOSRasterBand( CEOSDataset *, int );
68
69 CPLErr IReadBlock( int, int, void * ) override;
70 };
71
72 /************************************************************************/
73 /* CEOSRasterBand() */
74 /************************************************************************/
75
CEOSRasterBand(CEOSDataset * poDSIn,int nBandIn)76 CEOSRasterBand::CEOSRasterBand( CEOSDataset *poDSIn, int nBandIn )
77
78 {
79 poDS = poDSIn;
80 nBand = nBandIn;
81
82 eDataType = GDT_Byte;
83
84 nBlockXSize = poDS->GetRasterXSize();
85 nBlockYSize = 1;
86 }
87
88 /************************************************************************/
89 /* IReadBlock() */
90 /************************************************************************/
91
IReadBlock(CPL_UNUSED int nBlockXOff,int nBlockYOff,void * pImage)92 CPLErr CEOSRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
93 int nBlockYOff,
94 void * pImage )
95 {
96 CEOSDataset *poCEOS_DS = (CEOSDataset *) poDS;
97
98 CPLAssert( nBlockXOff == 0 );
99
100 return CEOSReadScanline(poCEOS_DS->psCEOS, nBand, nBlockYOff+1, pImage);
101 }
102
103 /************************************************************************/
104 /* ==================================================================== */
105 /* CEOSDataset */
106 /* ==================================================================== */
107 /************************************************************************/
108
109 /************************************************************************/
110 /* CEOSDataset() */
111 /************************************************************************/
112
CEOSDataset()113 CEOSDataset::CEOSDataset() :
114 psCEOS(nullptr)
115 {}
116
117 /************************************************************************/
118 /* ~CEOSDataset() */
119 /************************************************************************/
120
~CEOSDataset()121 CEOSDataset::~CEOSDataset()
122
123 {
124 FlushCache();
125 if( psCEOS )
126 CEOSClose( psCEOS );
127 }
128
129 /************************************************************************/
130 /* Open() */
131 /************************************************************************/
132
Open(GDALOpenInfo * poOpenInfo)133 GDALDataset *CEOSDataset::Open( GDALOpenInfo * poOpenInfo )
134
135 {
136 /* -------------------------------------------------------------------- */
137 /* Before trying CEOSOpen() we first verify that the first */
138 /* record is in fact a CEOS file descriptor record. */
139 /* -------------------------------------------------------------------- */
140 if( poOpenInfo->nHeaderBytes < 100 )
141 return nullptr;
142
143 if( poOpenInfo->pabyHeader[4] != 0x3f
144 || poOpenInfo->pabyHeader[5] != 0xc0
145 || poOpenInfo->pabyHeader[6] != 0x12
146 || poOpenInfo->pabyHeader[7] != 0x12 )
147 return nullptr;
148
149 /* -------------------------------------------------------------------- */
150 /* Try opening the dataset. */
151 /* -------------------------------------------------------------------- */
152 CEOSImage *psCEOS = CEOSOpen( poOpenInfo->pszFilename, "rb" );
153 if( psCEOS == nullptr )
154 return nullptr;
155
156 if( psCEOS->nBitsPerPixel != 8 )
157 {
158 CPLError( CE_Failure, CPLE_NotSupported,
159 "The CEOS driver cannot handle nBitsPerPixel = %d",
160 psCEOS->nBitsPerPixel );
161 CEOSClose(psCEOS);
162 return nullptr;
163 }
164
165 if( !GDALCheckDatasetDimensions(psCEOS->nPixels, psCEOS->nBands) ||
166 !GDALCheckBandCount(psCEOS->nBands, FALSE) )
167 {
168 CEOSClose( psCEOS );
169 return nullptr;
170 }
171
172 /* -------------------------------------------------------------------- */
173 /* Confirm the requested access is supported. */
174 /* -------------------------------------------------------------------- */
175 if( poOpenInfo->eAccess == GA_Update )
176 {
177 CEOSClose(psCEOS);
178 CPLError( CE_Failure, CPLE_NotSupported,
179 "The CEOS driver does not support update access to existing"
180 " datasets.\n" );
181 return nullptr;
182 }
183 /* -------------------------------------------------------------------- */
184 /* Create a corresponding GDALDataset. */
185 /* -------------------------------------------------------------------- */
186 CEOSDataset *poDS = new CEOSDataset();
187
188 poDS->psCEOS = psCEOS;
189
190 /* -------------------------------------------------------------------- */
191 /* Capture some information from the file that is of interest. */
192 /* -------------------------------------------------------------------- */
193 poDS->nRasterXSize = psCEOS->nPixels;
194 poDS->nRasterYSize = psCEOS->nLines;
195
196 /* -------------------------------------------------------------------- */
197 /* Create band information objects. */
198 /* -------------------------------------------------------------------- */
199 poDS->nBands = psCEOS->nBands;
200
201 for( int i = 0; i < poDS->nBands; i++ )
202 poDS->SetBand( i+1, new CEOSRasterBand( poDS, i+1 ) );
203
204 /* -------------------------------------------------------------------- */
205 /* Initialize any PAM information. */
206 /* -------------------------------------------------------------------- */
207 poDS->SetDescription( poOpenInfo->pszFilename );
208 poDS->TryLoadXML();
209
210 /* -------------------------------------------------------------------- */
211 /* Check for overviews. */
212 /* -------------------------------------------------------------------- */
213 poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
214
215 return poDS;
216 }
217
218 /************************************************************************/
219 /* GDALRegister_GTiff() */
220 /************************************************************************/
221
GDALRegister_CEOS()222 void GDALRegister_CEOS()
223
224 {
225 if( GDALGetDriverByName( "CEOS" ) != nullptr )
226 return;
227
228 GDALDriver *poDriver = new GDALDriver();
229
230 poDriver->SetDescription( "CEOS" );
231 poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" );
232 poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
233 "CEOS Image" );
234 poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
235 "drivers/raster/ceos.html" );
236 poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
237
238 poDriver->pfnOpen = CEOSDataset::Open;
239
240 GetGDALDriverManager()->RegisterDriver( poDriver );
241 }
242