1 : /******************************************************************************
2 : * $Id: elasdataset.cpp 16396 2009-02-22 20:49:52Z rouault $
3 : *
4 : * Project: ELAS Translator
5 : * Purpose: Complete implementation of ELAS translator module for GDAL.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
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 "gdal_pam.h"
31 :
32 : CPL_CVSID("$Id: elasdataset.cpp 16396 2009-02-22 20:49:52Z rouault $");
33 :
34 : CPL_C_START
35 : void GDALRegister_ELAS(void);
36 : CPL_C_END
37 :
38 : typedef struct {
39 : GInt32 NBIH; /* bytes in header, normaly 1024 */
40 : GInt32 NBPR; /* bytes per data record (all bands of scanline) */
41 : GInt32 IL; /* initial line - normally 1 */
42 : GInt32 LL; /* last line */
43 : GInt32 IE; /* initial element (pixel), normally 1 */
44 : GInt32 LE; /* last element (pixel) */
45 : GInt32 NC; /* number of channels (bands) */
46 : GInt32 H4321; /* header record identifier - always 4321. */
47 : char YLabel[4]; /* Should be "NOR" for UTM */
48 : GInt32 YOffset;/* topleft pixel center northing */
49 : char XLabel[4]; /* Should be "EAS" for UTM */
50 : GInt32 XOffset;/* topleft pixel center easting */
51 : float YPixSize;/* height of pixel in georef units */
52 : float XPixSize;/* width of pixel in georef units */
53 : float Matrix[4]; /* 2x2 transformation matrix. Should be
54 : 1,0,0,1 for pixel/line, or
55 : 1,0,0,-1 for UTM */
56 : GByte IH19[4];/* data type, and size flags */
57 : GInt32 IH20; /* number of secondary headers */
58 : char unused1[8];
59 : GInt32 LABL; /* used by LABL module */
60 : char HEAD; /* used by HEAD module */
61 : char Comment1[64];
62 : char Comment2[64];
63 : char Comment3[64];
64 : char Comment4[64];
65 : char Comment5[64];
66 : char Comment6[64];
67 : GUInt16 ColorTable[256]; /* RGB packed with 4 bits each */
68 : char unused2[32];
69 : } ELASHeader;
70 :
71 :
72 : /************************************************************************/
73 : /* ==================================================================== */
74 : /* ELASDataset */
75 : /* ==================================================================== */
76 : /************************************************************************/
77 :
78 : class ELASRasterBand;
79 :
80 : class ELASDataset : public GDALPamDataset
81 : {
82 : friend class ELASRasterBand;
83 :
84 : FILE *fp;
85 :
86 : ELASHeader sHeader;
87 : int bHeaderModified;
88 :
89 : GDALDataType eRasterDataType;
90 :
91 : int nLineOffset;
92 : int nBandOffset; // within a line.
93 :
94 : double adfGeoTransform[6];
95 :
96 : public:
97 : ELASDataset();
98 : ~ELASDataset();
99 :
100 : virtual CPLErr GetGeoTransform( double * );
101 : virtual CPLErr SetGeoTransform( double * );
102 :
103 : static GDALDataset *Open( GDALOpenInfo * );
104 : static GDALDataset *Create( const char * pszFilename,
105 : int nXSize, int nYSize, int nBands,
106 : GDALDataType eType, char ** papszParmList );
107 :
108 : virtual void FlushCache( void );
109 : };
110 :
111 : /************************************************************************/
112 : /* ==================================================================== */
113 : /* ELASRasterBand */
114 : /* ==================================================================== */
115 : /************************************************************************/
116 :
117 : class ELASRasterBand : public GDALPamRasterBand
118 74 : {
119 : friend class ELASDataset;
120 :
121 : public:
122 :
123 : ELASRasterBand( ELASDataset *, int );
124 :
125 : // should override RasterIO eventually.
126 :
127 : virtual CPLErr IReadBlock( int, int, void * );
128 : virtual CPLErr IWriteBlock( int, int, void * );
129 : };
130 :
131 :
132 : /************************************************************************/
133 : /* ELASRasterBand() */
134 : /************************************************************************/
135 :
136 74 : ELASRasterBand::ELASRasterBand( ELASDataset *poDS, int nBand )
137 :
138 : {
139 74 : this->poDS = poDS;
140 74 : this->nBand = nBand;
141 :
142 74 : this->eAccess = poDS->eAccess;
143 :
144 74 : eDataType = poDS->eRasterDataType;
145 :
146 74 : nBlockXSize = poDS->GetRasterXSize();
147 74 : nBlockYSize = 1;
148 74 : }
149 :
150 : /************************************************************************/
151 : /* IReadBlock() */
152 : /************************************************************************/
153 :
154 : CPLErr ELASRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
155 100 : void * pImage )
156 :
157 : {
158 100 : ELASDataset *poGDS = (ELASDataset *) poDS;
159 100 : CPLErr eErr = CE_None;
160 : long nOffset;
161 : int nDataSize;
162 :
163 100 : CPLAssert( nBlockXOff == 0 );
164 :
165 100 : nDataSize = GDALGetDataTypeSize(eDataType) * poGDS->GetRasterXSize() / 8;
166 100 : nOffset = poGDS->nLineOffset * nBlockYOff + 1024 + (nBand-1) * nDataSize;
167 :
168 : /* -------------------------------------------------------------------- */
169 : /* If we can't seek to the data, we will assume this is a newly */
170 : /* created file, and that the file hasn't been extended yet. */
171 : /* Just read as zeros. */
172 : /* -------------------------------------------------------------------- */
173 100 : if( VSIFSeek( poGDS->fp, nOffset, SEEK_SET ) != 0
174 : || VSIFRead( pImage, 1, nDataSize, poGDS->fp ) != (size_t) nDataSize )
175 : {
176 : CPLError( CE_Failure, CPLE_FileIO,
177 : "Seek or read of %d bytes at %ld failed.\n",
178 0 : nDataSize, nOffset );
179 0 : eErr = CE_Failure;
180 : }
181 :
182 100 : return eErr;
183 : }
184 :
185 : /************************************************************************/
186 : /* IWriteBlock() */
187 : /************************************************************************/
188 :
189 : CPLErr ELASRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
190 230 : void * pImage )
191 :
192 : {
193 230 : ELASDataset *poGDS = (ELASDataset *) poDS;
194 230 : CPLErr eErr = CE_None;
195 : long nOffset;
196 : int nDataSize;
197 :
198 230 : CPLAssert( nBlockXOff == 0 );
199 230 : CPLAssert( eAccess == GA_Update );
200 :
201 230 : nDataSize = GDALGetDataTypeSize(eDataType) * poGDS->GetRasterXSize() / 8;
202 230 : nOffset = poGDS->nLineOffset * nBlockYOff + 1024 + (nBand-1) * nDataSize;
203 :
204 230 : if( VSIFSeek( poGDS->fp, nOffset, SEEK_SET ) != 0
205 : || VSIFWrite( pImage, 1, nDataSize, poGDS->fp ) != (size_t) nDataSize )
206 : {
207 : CPLError( CE_Failure, CPLE_FileIO,
208 : "Seek or write of %d bytes at %ld failed.\n",
209 0 : nDataSize, nOffset );
210 0 : eErr = CE_Failure;
211 : }
212 :
213 230 : return eErr;
214 : }
215 :
216 : /************************************************************************/
217 : /* ==================================================================== */
218 : /* ELASDataset */
219 : /* ==================================================================== */
220 : /************************************************************************/
221 :
222 :
223 : /************************************************************************/
224 : /* ELASDataset() */
225 : /************************************************************************/
226 :
227 30 : ELASDataset::ELASDataset()
228 :
229 : {
230 30 : fp = NULL;
231 :
232 30 : adfGeoTransform[0] = 0.0;
233 30 : adfGeoTransform[1] = 1.0;
234 30 : adfGeoTransform[2] = 0.0;
235 30 : adfGeoTransform[3] = 0.0;
236 30 : adfGeoTransform[4] = 0.0;
237 30 : adfGeoTransform[5] = 1.0;
238 30 : }
239 :
240 : /************************************************************************/
241 : /* ~ELASDataset() */
242 : /************************************************************************/
243 :
244 30 : ELASDataset::~ELASDataset()
245 :
246 : {
247 30 : FlushCache();
248 :
249 30 : VSIFClose( fp );
250 30 : fp = NULL;
251 30 : }
252 :
253 : /************************************************************************/
254 : /* FlushCache() */
255 : /* */
256 : /* We also write out the header, if it is modified. */
257 : /************************************************************************/
258 :
259 30 : void ELASDataset::FlushCache()
260 :
261 : {
262 30 : GDALDataset::FlushCache();
263 :
264 30 : if( bHeaderModified )
265 : {
266 16 : VSIFSeek( fp, 0, SEEK_SET );
267 16 : VSIFWrite( &sHeader, 1024, 1, fp );
268 16 : bHeaderModified = FALSE;
269 : }
270 30 : }
271 :
272 :
273 : /************************************************************************/
274 : /* Open() */
275 : /************************************************************************/
276 :
277 11371 : GDALDataset *ELASDataset::Open( GDALOpenInfo * poOpenInfo )
278 :
279 : {
280 : /* -------------------------------------------------------------------- */
281 : /* First we check to see if the file has the expected header */
282 : /* bytes. */
283 : /* -------------------------------------------------------------------- */
284 11371 : if( poOpenInfo->nHeaderBytes < 256 )
285 9970 : return NULL;
286 :
287 1401 : if( CPL_MSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+0))) != 1024
288 : || CPL_MSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+28))) != 4321 )
289 : {
290 1371 : return NULL;
291 : }
292 :
293 : /* -------------------------------------------------------------------- */
294 : /* Create a corresponding GDALDataset. */
295 : /* -------------------------------------------------------------------- */
296 : ELASDataset *poDS;
297 : const char *pszAccess;
298 :
299 30 : if( poOpenInfo->eAccess == GA_Update )
300 17 : pszAccess = "r+b";
301 : else
302 13 : pszAccess = "rb";
303 :
304 30 : poDS = new ELASDataset();
305 :
306 30 : poDS->fp = VSIFOpen( poOpenInfo->pszFilename, pszAccess );
307 30 : if( poDS->fp == NULL )
308 : {
309 : CPLError( CE_Failure, CPLE_OpenFailed,
310 : "Attempt to open `%s' with acces `%s' failed.\n",
311 0 : poOpenInfo->pszFilename, pszAccess );
312 0 : return NULL;
313 : }
314 :
315 30 : poDS->eAccess = poOpenInfo->eAccess;
316 :
317 : /* -------------------------------------------------------------------- */
318 : /* Read the header information. */
319 : /* -------------------------------------------------------------------- */
320 30 : poDS->bHeaderModified = FALSE;
321 30 : if( VSIFRead( &(poDS->sHeader), 1024, 1, poDS->fp ) != 1 )
322 : {
323 : CPLError( CE_Failure, CPLE_FileIO,
324 : "Attempt to read 1024 byte header filed on file %s\n",
325 0 : poOpenInfo->pszFilename );
326 0 : return NULL;
327 : }
328 :
329 : /* -------------------------------------------------------------------- */
330 : /* Extract information of interest from the header. */
331 : /* -------------------------------------------------------------------- */
332 : int nStart, nEnd, nELASDataType, nBytesPerSample;
333 :
334 30 : poDS->nLineOffset = CPL_MSBWORD32( poDS->sHeader.NBPR );
335 :
336 30 : nStart = CPL_MSBWORD32( poDS->sHeader.IL );
337 30 : nEnd = CPL_MSBWORD32( poDS->sHeader.LL );
338 30 : poDS->nRasterYSize = nEnd - nStart + 1;
339 :
340 30 : nStart = CPL_MSBWORD32( poDS->sHeader.IE );
341 30 : nEnd = CPL_MSBWORD32( poDS->sHeader.LE );
342 30 : poDS->nRasterXSize = nEnd - nStart + 1;
343 :
344 30 : poDS->nBands = CPL_MSBWORD32( poDS->sHeader.NC );
345 :
346 30 : if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
347 : !GDALCheckBandCount(poDS->nBands, FALSE))
348 : {
349 0 : delete poDS;
350 0 : return NULL;
351 : }
352 :
353 30 : nELASDataType = (poDS->sHeader.IH19[2] & 0x7e) >> 2;
354 30 : nBytesPerSample = poDS->sHeader.IH19[3];
355 :
356 30 : if( nELASDataType == 0 && nBytesPerSample == 1 )
357 0 : poDS->eRasterDataType = GDT_Byte;
358 50 : else if( nELASDataType == 1 && nBytesPerSample == 1 )
359 20 : poDS->eRasterDataType = GDT_Byte;
360 15 : else if( nELASDataType == 16 && nBytesPerSample == 4 )
361 5 : poDS->eRasterDataType = GDT_Float32;
362 10 : else if( nELASDataType == 17 && nBytesPerSample == 8 )
363 5 : poDS->eRasterDataType = GDT_Float64;
364 : else
365 : {
366 0 : delete poDS;
367 : CPLError( CE_Failure, CPLE_AppDefined,
368 : "Unrecognised image data type %d, with BytesPerSample=%d.\n",
369 0 : nELASDataType, nBytesPerSample );
370 0 : return NULL;
371 : }
372 :
373 : /* -------------------------------------------------------------------- */
374 : /* Band offsets are always multiples of 256 within a multi-band */
375 : /* scanline of data. */
376 : /* -------------------------------------------------------------------- */
377 : poDS->nBandOffset =
378 30 : (poDS->nRasterXSize * GDALGetDataTypeSize(poDS->eRasterDataType)/8);
379 :
380 30 : if( poDS->nBandOffset % 256 != 0 )
381 : {
382 : poDS->nBandOffset =
383 30 : poDS->nBandOffset - (poDS->nBandOffset % 256) + 256;
384 : }
385 :
386 : /* -------------------------------------------------------------------- */
387 : /* Create band information objects. */
388 : /* -------------------------------------------------------------------- */
389 : int iBand;
390 :
391 208 : for( iBand = 0; iBand < poDS->nBands; iBand++ )
392 : {
393 74 : poDS->SetBand( iBand+1, new ELASRasterBand( poDS, iBand+1 ) );
394 : }
395 :
396 : /* -------------------------------------------------------------------- */
397 : /* Extract the projection coordinates, if present. */
398 : /* -------------------------------------------------------------------- */
399 30 : if( poDS->sHeader.XOffset != 0 )
400 : {
401 11 : CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
402 11 : CPL_MSBPTR32(&(poDS->sHeader.YPixSize));
403 :
404 : poDS->adfGeoTransform[0] =
405 11 : (GInt32) CPL_MSBWORD32(poDS->sHeader.XOffset);
406 11 : poDS->adfGeoTransform[1] = poDS->sHeader.XPixSize;
407 11 : poDS->adfGeoTransform[2] = 0.0;
408 : poDS->adfGeoTransform[3] =
409 11 : (GInt32) CPL_MSBWORD32(poDS->sHeader.YOffset);
410 11 : poDS->adfGeoTransform[4] = 0.0;
411 11 : poDS->adfGeoTransform[5] = -1.0 * ABS(poDS->sHeader.YPixSize);
412 :
413 11 : CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
414 11 : CPL_MSBPTR32(&(poDS->sHeader.YPixSize));
415 :
416 11 : poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
417 11 : poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;
418 : }
419 : else
420 : {
421 19 : poDS->adfGeoTransform[0] = 0.0;
422 19 : poDS->adfGeoTransform[1] = 1.0;
423 19 : poDS->adfGeoTransform[2] = 0.0;
424 19 : poDS->adfGeoTransform[3] = 0.0;
425 19 : poDS->adfGeoTransform[4] = 0.0;
426 19 : poDS->adfGeoTransform[5] = 1.0;
427 : }
428 :
429 : /* -------------------------------------------------------------------- */
430 : /* Initialize any PAM information. */
431 : /* -------------------------------------------------------------------- */
432 30 : poDS->SetDescription( poOpenInfo->pszFilename );
433 30 : poDS->TryLoadXML();
434 :
435 30 : return( poDS );
436 : }
437 :
438 : /************************************************************************/
439 : /* Create() */
440 : /* */
441 : /* Create a new GeoTIFF or TIFF file. */
442 : /************************************************************************/
443 :
444 : GDALDataset *ELASDataset::Create( const char * pszFilename,
445 : int nXSize, int nYSize, int nBands,
446 : GDALDataType eType,
447 42 : char ** /* notdef: papszParmList */ )
448 :
449 : {
450 : int nBandOffset;
451 :
452 : /* -------------------------------------------------------------------- */
453 : /* Verify input options. */
454 : /* -------------------------------------------------------------------- */
455 42 : if (nBands <= 0)
456 : {
457 : CPLError( CE_Failure, CPLE_NotSupported,
458 1 : "ELAS driver does not support %d bands.\n", nBands);
459 1 : return NULL;
460 : }
461 :
462 41 : if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_Float64 )
463 : {
464 : CPLError( CE_Failure, CPLE_AppDefined,
465 : "Attempt to create an ELAS dataset with an illegal\n"
466 : "data type (%d).\n",
467 24 : eType );
468 :
469 24 : return NULL;
470 : }
471 :
472 : /* -------------------------------------------------------------------- */
473 : /* Try to create the file. */
474 : /* -------------------------------------------------------------------- */
475 : FILE *fp;
476 :
477 17 : fp = VSIFOpen( pszFilename, "w" );
478 :
479 17 : if( fp == NULL )
480 : {
481 : CPLError( CE_Failure, CPLE_OpenFailed,
482 : "Attempt to create file `%s' failed.\n",
483 0 : pszFilename );
484 0 : return NULL;
485 : }
486 :
487 : /* -------------------------------------------------------------------- */
488 : /* How long will each band of a scanline be? */
489 : /* -------------------------------------------------------------------- */
490 17 : nBandOffset = nXSize * GDALGetDataTypeSize(eType)/8;
491 :
492 17 : if( nBandOffset % 256 != 0 )
493 : {
494 17 : nBandOffset = nBandOffset - (nBandOffset % 256) + 256;
495 : }
496 :
497 : /* -------------------------------------------------------------------- */
498 : /* Setup header data block. */
499 : /* */
500 : /* Note that CPL_MSBWORD32() will swap little endian words to */
501 : /* big endian on little endian platforms. */
502 : /* -------------------------------------------------------------------- */
503 : ELASHeader sHeader;
504 :
505 17 : memset( &sHeader, 0, 1024 );
506 :
507 17 : sHeader.NBIH = CPL_MSBWORD32(1024);
508 :
509 17 : sHeader.NBPR = CPL_MSBWORD32(nBands * nBandOffset);
510 :
511 17 : sHeader.IL = CPL_MSBWORD32(1);
512 17 : sHeader.LL = CPL_MSBWORD32(nYSize);
513 :
514 17 : sHeader.IE = CPL_MSBWORD32(1);
515 17 : sHeader.LE = CPL_MSBWORD32(nXSize);
516 :
517 17 : sHeader.NC = CPL_MSBWORD32(nBands);
518 :
519 17 : sHeader.H4321 = CPL_MSBWORD32(4321);
520 :
521 17 : sHeader.IH19[0] = 0x04;
522 17 : sHeader.IH19[1] = 0xd2;
523 17 : sHeader.IH19[3] = (GByte) (GDALGetDataTypeSize(eType) / 8);
524 :
525 17 : if( eType == GDT_Byte )
526 11 : sHeader.IH19[2] = 1 << 2;
527 6 : else if( eType == GDT_Float32 )
528 3 : sHeader.IH19[2] = 16 << 2;
529 3 : else if( eType == GDT_Float64 )
530 3 : sHeader.IH19[2] = 17 << 2;
531 :
532 : /* -------------------------------------------------------------------- */
533 : /* Write the header data. */
534 : /* -------------------------------------------------------------------- */
535 17 : VSIFWrite( &sHeader, 1024, 1, fp );
536 :
537 : /* -------------------------------------------------------------------- */
538 : /* Now write out zero data for all the imagery. This is */
539 : /* inefficient, but simplies the IReadBlock() / IWriteBlock() logic.*/
540 : /* -------------------------------------------------------------------- */
541 : GByte *pabyLine;
542 :
543 17 : pabyLine = (GByte *) CPLCalloc(nBandOffset,nBands);
544 1007 : for( int iLine = 0; iLine < nYSize; iLine++ )
545 : {
546 990 : if( VSIFWrite( pabyLine, 1, nBandOffset, fp ) != (size_t) nBandOffset )
547 : {
548 : CPLError( CE_Failure, CPLE_FileIO,
549 : "Error writing ELAS image data ... likely insufficient"
550 0 : " disk space.\n" );
551 0 : VSIFClose( fp );
552 0 : CPLFree( pabyLine );
553 0 : return NULL;
554 : }
555 : }
556 :
557 17 : CPLFree( pabyLine );
558 :
559 17 : VSIFClose( fp );
560 :
561 : /* -------------------------------------------------------------------- */
562 : /* Try to return a regular handle on the file. */
563 : /* -------------------------------------------------------------------- */
564 17 : return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
565 : }
566 :
567 : /************************************************************************/
568 : /* GetGeoTransform() */
569 : /************************************************************************/
570 :
571 0 : CPLErr ELASDataset::GetGeoTransform( double * padfTransform )
572 :
573 : {
574 0 : memcpy( padfTransform, adfGeoTransform, sizeof(double)*6 );
575 :
576 0 : return( CE_None );
577 : }
578 :
579 : /************************************************************************/
580 : /* SetGeoTransform() */
581 : /************************************************************************/
582 :
583 16 : CPLErr ELASDataset::SetGeoTransform( double * padfTransform )
584 :
585 : {
586 : /* -------------------------------------------------------------------- */
587 : /* I don't think it supports rotation, but perhaps it is possible */
588 : /* for us to use the 2x2 transform matrix to accomplish some */
589 : /* sort of rotation. */
590 : /* -------------------------------------------------------------------- */
591 16 : if( padfTransform[2] != 0.0 || padfTransform[4] != 0.0 )
592 : {
593 : CPLError( CE_Failure, CPLE_AppDefined,
594 : "Attempt to set rotated geotransform on ELAS file.\n"
595 0 : "ELAS does not support rotation.\n" );
596 :
597 0 : return CE_Failure;
598 : }
599 :
600 : /* -------------------------------------------------------------------- */
601 : /* Remember the new transform, and update the header. */
602 : /* -------------------------------------------------------------------- */
603 : int nXOff, nYOff;
604 :
605 16 : memcpy( adfGeoTransform, padfTransform, sizeof(double)*6 );
606 :
607 16 : bHeaderModified = TRUE;
608 :
609 16 : nXOff = (int) (adfGeoTransform[0] + adfGeoTransform[1]*0.5);
610 16 : nYOff = (int) (adfGeoTransform[3] + adfGeoTransform[5]*0.5);
611 :
612 16 : sHeader.XOffset = CPL_MSBWORD32(nXOff);
613 16 : sHeader.YOffset = CPL_MSBWORD32(nYOff);
614 :
615 16 : sHeader.XPixSize = (float) ABS(adfGeoTransform[1]);
616 16 : sHeader.YPixSize = (float) ABS(adfGeoTransform[5]);
617 :
618 16 : CPL_MSBPTR32(&(sHeader.XPixSize));
619 16 : CPL_MSBPTR32(&(sHeader.YPixSize));
620 :
621 16 : strncpy( sHeader.YLabel, "NOR ", 4 );
622 16 : strncpy( sHeader.XLabel, "EAS ", 4 );
623 :
624 16 : sHeader.Matrix[0] = 1.0;
625 16 : sHeader.Matrix[1] = 0.0;
626 16 : sHeader.Matrix[2] = 0.0;
627 16 : sHeader.Matrix[3] = -1.0;
628 :
629 16 : CPL_MSBPTR32(&(sHeader.Matrix[0]));
630 16 : CPL_MSBPTR32(&(sHeader.Matrix[1]));
631 16 : CPL_MSBPTR32(&(sHeader.Matrix[2]));
632 16 : CPL_MSBPTR32(&(sHeader.Matrix[3]));
633 :
634 16 : return( CE_None );
635 : }
636 :
637 :
638 : /************************************************************************/
639 : /* GDALRegister_ELAS() */
640 : /************************************************************************/
641 :
642 409 : void GDALRegister_ELAS()
643 :
644 : {
645 : GDALDriver *poDriver;
646 :
647 409 : if( GDALGetDriverByName( "ELAS" ) == NULL )
648 : {
649 392 : poDriver = new GDALDriver();
650 :
651 392 : poDriver->SetDescription( "ELAS" );
652 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
653 392 : "ELAS" );
654 : poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES,
655 392 : "Byte Float32 Float64" );
656 :
657 392 : poDriver->pfnOpen = ELASDataset::Open;
658 392 : poDriver->pfnCreate = ELASDataset::Create;
659 :
660 392 : GetGDALDriverManager()->RegisterDriver( poDriver );
661 : }
662 409 : }
|