1 : /******************************************************************************
2 : * $Id: gscdataset.cpp 21715 2011-02-13 19:18:59Z rouault $
3 : *
4 : * Project: GSC Geogrid format driver.
5 : * Purpose: Implements support for reading and writing GSC Geogrid format.
6 : * Author: Frank Warmerdam <warmerdam@pobox.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.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 "rawdataset.h"
31 : #include "cpl_string.h"
32 :
33 : CPL_CVSID("$Id: gscdataset.cpp 21715 2011-02-13 19:18:59Z rouault $");
34 :
35 : /************************************************************************/
36 : /* ==================================================================== */
37 : /* GSCDataset */
38 : /* ==================================================================== */
39 : /************************************************************************/
40 :
41 : class GSCDataset : public RawDataset
42 : {
43 : VSILFILE *fpImage; // image data file.
44 :
45 : double adfGeoTransform[6];
46 :
47 : public:
48 : GSCDataset();
49 : ~GSCDataset();
50 :
51 : CPLErr GetGeoTransform( double * padfTransform );
52 :
53 : static GDALDataset *Open( GDALOpenInfo * );
54 : };
55 :
56 : /************************************************************************/
57 : /* GSCDataset() */
58 : /************************************************************************/
59 :
60 1 : GSCDataset::GSCDataset()
61 : {
62 1 : adfGeoTransform[0] = 0.0;
63 1 : adfGeoTransform[1] = 1.0;
64 1 : adfGeoTransform[2] = 0.0;
65 1 : adfGeoTransform[3] = 0.0;
66 1 : adfGeoTransform[4] = 0.0;
67 1 : adfGeoTransform[5] = 1.0;
68 1 : fpImage = NULL;
69 1 : }
70 :
71 : /************************************************************************/
72 : /* ~GSCDataset() */
73 : /************************************************************************/
74 :
75 1 : GSCDataset::~GSCDataset()
76 :
77 : {
78 1 : FlushCache();
79 1 : if( fpImage != NULL )
80 1 : VSIFCloseL( fpImage );
81 1 : }
82 :
83 : /************************************************************************/
84 : /* GetGeoTransform() */
85 : /************************************************************************/
86 :
87 0 : CPLErr GSCDataset::GetGeoTransform( double * padfTransform )
88 :
89 : {
90 0 : memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
91 :
92 0 : return CE_None;
93 : }
94 :
95 : /************************************************************************/
96 : /* Open() */
97 : /************************************************************************/
98 :
99 12041 : GDALDataset *GSCDataset::Open( GDALOpenInfo * poOpenInfo )
100 :
101 : {
102 : int nPixels, nLines, i, nRecordLen;
103 :
104 : /* -------------------------------------------------------------------- */
105 : /* Does this plausible look like a GSC Geogrid file? */
106 : /* -------------------------------------------------------------------- */
107 12041 : if( poOpenInfo->nHeaderBytes < 20 )
108 11342 : return NULL;
109 :
110 702 : if( poOpenInfo->pabyHeader[12] != 0x02
111 1 : || poOpenInfo->pabyHeader[13] != 0x00
112 1 : || poOpenInfo->pabyHeader[14] != 0x00
113 1 : || poOpenInfo->pabyHeader[15] != 0x00 )
114 698 : return NULL;
115 :
116 1 : nRecordLen = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[0]);
117 1 : nPixels = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[1]);
118 1 : nLines = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[2]);
119 :
120 1 : if( nPixels < 1 || nLines < 1 || nPixels > 100000 || nLines > 100000 )
121 0 : return NULL;
122 :
123 1 : if( nRecordLen != nPixels * 4 )
124 0 : return NULL;
125 :
126 : /* -------------------------------------------------------------------- */
127 : /* Confirm the requested access is supported. */
128 : /* -------------------------------------------------------------------- */
129 1 : if( poOpenInfo->eAccess == GA_Update )
130 : {
131 : CPLError( CE_Failure, CPLE_NotSupported,
132 : "The GSC driver does not support update access to existing"
133 0 : " datasets.\n" );
134 0 : return NULL;
135 : }
136 :
137 1 : nRecordLen += 8; /* for record length markers */
138 :
139 : /* -------------------------------------------------------------------- */
140 : /* Create a corresponding GDALDataset. */
141 : /* -------------------------------------------------------------------- */
142 : GSCDataset *poDS;
143 :
144 1 : poDS = new GSCDataset();
145 :
146 1 : poDS->nRasterXSize = nPixels;
147 1 : poDS->nRasterYSize = nLines;
148 :
149 : /* -------------------------------------------------------------------- */
150 : /* Assume ownership of the file handled from the GDALOpenInfo. */
151 : /* -------------------------------------------------------------------- */
152 1 : poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb");
153 1 : if (poDS->fpImage == NULL)
154 : {
155 0 : delete poDS;
156 0 : return NULL;
157 : }
158 :
159 : /* -------------------------------------------------------------------- */
160 : /* Read the header information in the second record. */
161 : /* -------------------------------------------------------------------- */
162 : float afHeaderInfo[8];
163 :
164 1 : if( VSIFSeekL( poDS->fpImage, nRecordLen + 12, SEEK_SET ) != 0
165 : || VSIFReadL( afHeaderInfo, sizeof(float), 8, poDS->fpImage ) != 8 )
166 : {
167 : CPLError( CE_Failure, CPLE_FileIO,
168 : "Failure reading second record of GSC file with %d record length.",
169 0 : nRecordLen );
170 0 : delete poDS;
171 0 : return NULL;
172 : }
173 :
174 1 : for( i = 0; i < 8; i++ )
175 : {
176 : CPL_LSBPTR32( afHeaderInfo + i );
177 : }
178 :
179 1 : poDS->adfGeoTransform[0] = afHeaderInfo[2];
180 1 : poDS->adfGeoTransform[1] = afHeaderInfo[0];
181 1 : poDS->adfGeoTransform[2] = 0.0;
182 1 : poDS->adfGeoTransform[3] = afHeaderInfo[5];
183 1 : poDS->adfGeoTransform[4] = 0.0;
184 1 : poDS->adfGeoTransform[5] = -afHeaderInfo[1];
185 :
186 : /* -------------------------------------------------------------------- */
187 : /* Create band information objects. */
188 : /* -------------------------------------------------------------------- */
189 : RawRasterBand *poBand;
190 : #ifdef CPL_LSB
191 1 : int bNative = TRUE;
192 : #else
193 : int bNative = FALSE;
194 : #endif
195 :
196 : poBand = new RawRasterBand( poDS, 1, poDS->fpImage,
197 : nRecordLen * 2 + 4,
198 : sizeof(float), nRecordLen,
199 1 : GDT_Float32, bNative, TRUE );
200 1 : poDS->SetBand( 1, poBand );
201 :
202 1 : poBand->SetNoDataValue( -1.0000000150474662199e+30 );
203 :
204 : /* -------------------------------------------------------------------- */
205 : /* Initialize any PAM information. */
206 : /* -------------------------------------------------------------------- */
207 1 : poDS->SetDescription( poOpenInfo->pszFilename );
208 1 : poDS->TryLoadXML();
209 :
210 : /* -------------------------------------------------------------------- */
211 : /* Check for overviews. */
212 : /* -------------------------------------------------------------------- */
213 1 : poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
214 :
215 1 : return( poDS );
216 : }
217 :
218 : /************************************************************************/
219 : /* GDALRegister_GSC() */
220 : /************************************************************************/
221 :
222 582 : void GDALRegister_GSC()
223 :
224 : {
225 : GDALDriver *poDriver;
226 :
227 582 : if( GDALGetDriverByName( "GSC" ) == NULL )
228 : {
229 561 : poDriver = new GDALDriver();
230 :
231 561 : poDriver->SetDescription( "GSC" );
232 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
233 561 : "GSC Geogrid" );
234 : // poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
235 : // "frmt_various.html#GSC" );
236 561 : poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
237 :
238 561 : poDriver->pfnOpen = GSCDataset::Open;
239 :
240 561 : GetGDALDriverManager()->RegisterDriver( poDriver );
241 : }
242 582 : }
243 :
|