1 : /******************************************************************************
2 : * $Id: gscdataset.cpp 17664 2009-09-21 21:16:45Z 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 17664 2009-09-21 21:16:45Z rouault $");
34 :
35 : /************************************************************************/
36 : /* ==================================================================== */
37 : /* GSCDataset */
38 : /* ==================================================================== */
39 : /************************************************************************/
40 :
41 : class GSCDataset : public RawDataset
42 : {
43 : FILE *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 2 : GSCDataset::~GSCDataset()
76 :
77 : {
78 1 : FlushCache();
79 1 : if( fpImage != NULL )
80 1 : VSIFClose( fpImage );
81 2 : }
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 8558 : 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 8558 : if( poOpenInfo->nHeaderBytes < 20 || poOpenInfo->fp == NULL )
108 8323 : return NULL;
109 :
110 238 : if( poOpenInfo->pabyHeader[12] != 0x02
111 1 : || poOpenInfo->pabyHeader[13] != 0x00
112 1 : || poOpenInfo->pabyHeader[14] != 0x00
113 1 : || poOpenInfo->pabyHeader[15] != 0x00 )
114 234 : 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 = poOpenInfo->fp;
153 1 : poOpenInfo->fp = NULL;
154 :
155 : /* -------------------------------------------------------------------- */
156 : /* Read the header information in the second record. */
157 : /* -------------------------------------------------------------------- */
158 : float afHeaderInfo[8];
159 :
160 2 : if( VSIFSeek( poDS->fpImage, nRecordLen + 12, SEEK_SET ) != 0
161 : || VSIFRead( afHeaderInfo, sizeof(float), 8, poDS->fpImage ) != 8 )
162 : {
163 : CPLError( CE_Failure, CPLE_FileIO,
164 : "Failure reading second record of GSC file with %d record length.",
165 0 : nRecordLen );
166 0 : delete poDS;
167 0 : return NULL;
168 : }
169 :
170 1 : for( i = 0; i < 8; i++ )
171 : {
172 : CPL_LSBPTR32( afHeaderInfo + i );
173 : }
174 :
175 1 : poDS->adfGeoTransform[0] = afHeaderInfo[2];
176 1 : poDS->adfGeoTransform[1] = afHeaderInfo[0];
177 1 : poDS->adfGeoTransform[2] = 0.0;
178 1 : poDS->adfGeoTransform[3] = afHeaderInfo[5];
179 1 : poDS->adfGeoTransform[4] = 0.0;
180 1 : poDS->adfGeoTransform[5] = -afHeaderInfo[1];
181 :
182 : /* -------------------------------------------------------------------- */
183 : /* Create band information objects. */
184 : /* -------------------------------------------------------------------- */
185 : RawRasterBand *poBand;
186 : #ifdef CPL_LSB
187 1 : int bNative = TRUE;
188 : #else
189 : int bNative = FALSE;
190 : #endif
191 :
192 : poBand = new RawRasterBand( poDS, 1, poDS->fpImage,
193 : nRecordLen * 2 + 4,
194 : sizeof(float), nRecordLen,
195 1 : GDT_Float32, bNative, FALSE );
196 1 : poDS->SetBand( 1, poBand );
197 :
198 1 : poBand->SetNoDataValue( -1.0000000150474662199e+30 );
199 :
200 : /* -------------------------------------------------------------------- */
201 : /* Initialize any PAM information. */
202 : /* -------------------------------------------------------------------- */
203 1 : poDS->SetDescription( poOpenInfo->pszFilename );
204 1 : poDS->TryLoadXML();
205 :
206 : /* -------------------------------------------------------------------- */
207 : /* Check for overviews. */
208 : /* -------------------------------------------------------------------- */
209 1 : poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
210 :
211 1 : return( poDS );
212 : }
213 :
214 : /************************************************************************/
215 : /* GDALRegister_GSC() */
216 : /************************************************************************/
217 :
218 338 : void GDALRegister_GSC()
219 :
220 : {
221 : GDALDriver *poDriver;
222 :
223 338 : if( GDALGetDriverByName( "GSC" ) == NULL )
224 : {
225 336 : poDriver = new GDALDriver();
226 :
227 336 : poDriver->SetDescription( "GSC" );
228 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
229 336 : "GSC Geogrid" );
230 : // poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
231 : // "frmt_various.html#GSC" );
232 :
233 336 : poDriver->pfnOpen = GSCDataset::Open;
234 :
235 336 : GetGDALDriverManager()->RegisterDriver( poDriver );
236 : }
237 338 : }
238 :
|