1 : /******************************************************************************
2 : * $Id: jaxapalsardataset.cpp 17664 2009-09-21 21:16:45Z rouault $
3 : *
4 : * Project: PALSAR JAXA imagery reader
5 : * Purpose: Support for PALSAR L1.1/1.5 imagery and appropriate metadata from
6 : * JAXA and JAXA-supported ground stations (ASF, ESA, etc.). This
7 : * driver does not support ERSDAC products.
8 : * Author: Philippe Vachon <philippe@cowpig.ca>
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 2007, Philippe P. Vachon <philippe@cowpig.ca>
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "gdal_pam.h"
33 :
34 : CPL_CVSID("$Id: jaxapalsardataset.cpp 17664 2009-09-21 21:16:45Z rouault $");
35 :
36 : CPL_C_START
37 : void GDALRegister_PALSARJaxa(void);
38 : CPL_C_END
39 :
40 : #if defined(WIN32) || defined(WIN32CE)
41 : #define SEP_STRING "\\"
42 : #else
43 : #define SEP_STRING "/"
44 : #endif
45 :
46 : /* read binary fields */
47 : #ifdef CPL_LSB
48 : #define READ_WORD(f, x) \
49 : do { \
50 : VSIFReadL( &(x), 4, 1, (f) ); \
51 : (x) = CPL_SWAP32( (x) ); \
52 : } while (0);
53 : #define READ_SHORT(f, x) \
54 : do { \
55 : VSIFReadL( &(x), 2, 1, (f) ); \
56 : (x) = CPL_SWAP16( (x) ); \
57 : } while (0);
58 : #else
59 : #define READ_WORD(f, x) do { VSIFReadL( &(x), 4, 1, (f) ); } while (0);
60 : #define READ_SHORT(f, x) do { VSIFReadL( &(x), 2, 1, (f) ); } while (0);
61 : #endif /* def CPL_LSB */
62 : #define READ_BYTE(f, x) do { VSIFReadL( &(x), 1, 1, (f) ); } while (0);
63 :
64 : /* read floating point value stored as ASCII */
65 : #define READ_CHAR_FLOAT(n, l, f) \
66 : do {\
67 : char psBuf[(l+1)]; \
68 : psBuf[(l)] = '\0'; \
69 : VSIFReadL( &psBuf, (l), 1, (f) );\
70 : (n) = CPLAtof( psBuf );\
71 : } while (0);
72 :
73 : /* read numbers stored as ASCII */
74 : #define READ_CHAR_VAL(x, n, f) \
75 : do { \
76 : char psBuf[(n+1)]; \
77 : psBuf[(n)] = '\0';\
78 : VSIFReadL( &psBuf, (n), 1, (f) ); \
79 : (x) = atoi(psBuf); \
80 : } while (0);
81 :
82 : /* read string fields
83 : * note: string must be size of field to be extracted + 1
84 : */
85 : #define READ_STRING(s, n, f) \
86 : do { \
87 : VSIFReadL( &(s), 1, (n), (f) ); \
88 : (s)[(n)] = '\0'; \
89 : } while (0);
90 :
91 : /*************************************************************************/
92 : /* a few key offsets in the volume directory file */
93 : #define VOL_DESC_RECORD_LENGTH 360
94 : #define FILE_PTR_RECORD_LENGTH 360
95 : #define NUM_RECORDS_OFFSET 160
96 :
97 : /* a few key offsets and values within the File Pointer record */
98 : #define REF_FILE_CLASS_CODE_OFFSET 66
99 : #define REF_FILE_CLASS_CODE_LENGTH 4
100 : #define FILE_NAME_OFFSET 310
101 :
102 : /* some image option descriptor records */
103 : #define BITS_PER_SAMPLE_OFFSET 216
104 : #define BITS_PER_SAMPLE_LENGTH 4
105 : #define SAMPLES_PER_GROUP_OFFSET 220
106 : #define SAMPLES_PER_GROUP_LENGTH 4
107 : #define NUMBER_LINES_OFFSET 236
108 : #define NUMBER_LINES_LENGTH 8
109 : #define SAR_DATA_RECORD_LENGTH_OFFSET 186
110 : #define SAR_DATA_RECORD_LENGTH_LENGTH 6
111 :
112 : #define IMAGE_OPT_DESC_LENGTH 720
113 :
114 : #define SIG_DAT_REC_OFFSET 412
115 : #define PROC_DAT_REC_OFFSET 192
116 :
117 : /* metadata to be extracted from the leader file */
118 : #define LEADER_FILE_DESCRIPTOR_LENGTH 720
119 : #define DATA_SET_SUMMARY_LENGTH 4096
120 :
121 : /* relative to end of leader file descriptor */
122 : #define EFFECTIVE_LOOKS_AZIMUTH_OFFSET 1174 /* floating point text */
123 : #define EFFECTIVE_LOOKS_AZIMUTH_LENGTH 16
124 :
125 : /* relative to leader file descriptor + dataset summary length */
126 : #define PIXEL_SPACING_OFFSET 92
127 : #define LINE_SPACING_OFFSET 108
128 : #define ALPHANUMERIC_PROJECTION_NAME_OFFSET 412
129 : #define TOP_LEFT_LAT_OFFSET 1072
130 : #define TOP_LEFT_LON_OFFSET 1088
131 : #define TOP_RIGHT_LAT_OFFSET 1104
132 : #define TOP_RIGHT_LON_OFFSET 1120
133 : #define BOTTOM_RIGHT_LAT_OFFSET 1136
134 : #define BOTTOM_RIGHT_LON_OFFSET 1152
135 : #define BOTTOM_LEFT_LAT_OFFSET 1168
136 : #define BOTTOM_LEFT_LON_OFFSET 1184
137 :
138 : /* a few useful enums */
139 : enum eFileType {
140 : level_11 = 0,
141 : level_15
142 : };
143 :
144 : enum ePolarization {
145 : hh = 0,
146 : hv,
147 : vh,
148 : vv
149 : };
150 :
151 : /************************************************************************/
152 : /* ==================================================================== */
153 : /* PALSARJaxaDataset */
154 : /* ==================================================================== */
155 : /************************************************************************/
156 :
157 : class PALSARJaxaRasterBand;
158 :
159 : class PALSARJaxaDataset : public GDALPamDataset {
160 : friend class PALSARJaxaRasterBand;
161 : private:
162 : GDAL_GCP *pasGCPList;
163 : int nGCPCount;
164 : eFileType nFileType;
165 : public:
166 : PALSARJaxaDataset();
167 : ~PALSARJaxaDataset();
168 :
169 : int GetGCPCount();
170 : const GDAL_GCP *GetGCPs();
171 :
172 : static GDALDataset *Open( GDALOpenInfo *poOpenInfo );
173 : static int Identify( GDALOpenInfo *poOpenInfo );
174 : static void ReadMetadata( PALSARJaxaDataset *poDS, FILE *fp );
175 : };
176 :
177 0 : PALSARJaxaDataset::PALSARJaxaDataset()
178 : {
179 0 : pasGCPList = NULL;
180 0 : nGCPCount = 0;
181 0 : }
182 :
183 0 : PALSARJaxaDataset::~PALSARJaxaDataset()
184 : {
185 0 : if( nGCPCount > 0 )
186 : {
187 0 : GDALDeinitGCPs( nGCPCount, pasGCPList );
188 0 : CPLFree( pasGCPList );
189 : }
190 0 : }
191 :
192 : /************************************************************************/
193 : /* ==================================================================== */
194 : /* PALSARJaxaRasterBand */
195 : /* ==================================================================== */
196 : /************************************************************************/
197 :
198 : class PALSARJaxaRasterBand : public GDALRasterBand {
199 : FILE *fp;
200 : int nRasterXSize;
201 : int nRasterYSize;
202 : ePolarization nPolarization;
203 : eFileType nFileType;
204 : int nBitsPerSample;
205 : int nSamplesPerGroup;
206 : int nRecordSize;
207 : public:
208 : PALSARJaxaRasterBand( PALSARJaxaDataset *poDS, int nBand, FILE *fp );
209 : ~PALSARJaxaRasterBand();
210 :
211 : CPLErr IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage );
212 : };
213 :
214 : /************************************************************************/
215 : /* PALSARJaxaRasterBand() */
216 : /************************************************************************/
217 :
218 0 : PALSARJaxaRasterBand::PALSARJaxaRasterBand( PALSARJaxaDataset *poDS,
219 0 : int nBand, FILE *fp )
220 : {
221 0 : this->fp = fp;
222 :
223 : /* Read image options record to determine the type of data */
224 0 : VSIFSeekL( fp, BITS_PER_SAMPLE_OFFSET, SEEK_SET );
225 0 : nBitsPerSample = 0;
226 0 : nSamplesPerGroup = 0;
227 0 : READ_CHAR_VAL( nBitsPerSample, BITS_PER_SAMPLE_LENGTH, fp );
228 0 : READ_CHAR_VAL( nSamplesPerGroup, SAMPLES_PER_GROUP_LENGTH, fp );
229 :
230 0 : if (nBitsPerSample == 32 && nSamplesPerGroup == 2) {
231 0 : eDataType = GDT_CFloat32;
232 0 : nFileType = level_11;
233 : }
234 : else {
235 0 : eDataType = GDT_Int16;
236 0 : nFileType = level_15;
237 : }
238 :
239 0 : poDS->nFileType = nFileType;
240 :
241 : /* Read number of range/azimuth lines */
242 0 : VSIFSeekL( fp, NUMBER_LINES_OFFSET, SEEK_SET );
243 0 : READ_CHAR_VAL( nRasterYSize, NUMBER_LINES_LENGTH, fp );
244 0 : VSIFSeekL( fp, SAR_DATA_RECORD_LENGTH_OFFSET, SEEK_SET );
245 0 : READ_CHAR_VAL( nRecordSize, SAR_DATA_RECORD_LENGTH_LENGTH, fp );
246 : nRasterXSize = (nRecordSize -
247 : (nFileType == level_11 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET))
248 0 : / ((nBitsPerSample / 8) * nSamplesPerGroup);
249 :
250 0 : poDS->nRasterXSize = nRasterXSize;
251 0 : poDS->nRasterYSize = nRasterYSize;
252 :
253 : /* Polarization */
254 0 : switch (nBand) {
255 : case 0:
256 0 : nPolarization = hh;
257 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "HH" );
258 0 : break;
259 : case 1:
260 0 : nPolarization = hv;
261 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "HV" );
262 0 : break;
263 : case 2:
264 0 : nPolarization = vh;
265 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "VH" );
266 0 : break;
267 : case 3:
268 0 : nPolarization = vv;
269 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "VV" );
270 : break;
271 : }
272 :
273 : /* size of block we can read */
274 0 : nBlockXSize = nRasterXSize;
275 0 : nBlockYSize = 1;
276 :
277 : /* set the file pointer to the first SAR data record */
278 0 : VSIFSeekL( fp, IMAGE_OPT_DESC_LENGTH, SEEK_SET );
279 0 : }
280 :
281 : /************************************************************************/
282 : /* ~PALSARJaxaRasterBand() */
283 : /************************************************************************/
284 :
285 0 : PALSARJaxaRasterBand::~PALSARJaxaRasterBand()
286 : {
287 0 : if (fp)
288 0 : VSIFCloseL(fp);
289 0 : }
290 :
291 : /************************************************************************/
292 : /* IReadBlock() */
293 : /************************************************************************/
294 :
295 0 : CPLErr PALSARJaxaRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
296 : void *pImage )
297 : {
298 0 : int nNumBytes = 0;
299 0 : if (nFileType == level_11) {
300 0 : nNumBytes = 8;
301 : }
302 : else {
303 0 : nNumBytes = 2;
304 : }
305 :
306 : int nOffset = IMAGE_OPT_DESC_LENGTH + ((nBlockYOff - 1) * nRecordSize) +
307 0 : (nFileType == level_11 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET);
308 :
309 0 : VSIFSeekL( fp, nOffset, SEEK_SET );
310 0 : VSIFReadL( pImage, nNumBytes, nRasterXSize, fp );
311 :
312 : #ifdef CPL_LSB
313 0 : if (nFileType == level_11)
314 0 : GDALSwapWords( pImage, 4, nBlockXSize * 2, 4 );
315 : else
316 0 : GDALSwapWords( pImage, 2, nBlockXSize, 2 );
317 : #endif
318 :
319 0 : return CE_None;
320 : }
321 :
322 :
323 : /************************************************************************/
324 : /* ==================================================================== */
325 : /* PALSARJaxaDataset */
326 : /* ==================================================================== */
327 : /************************************************************************/
328 :
329 : /************************************************************************/
330 : /* ReadMetadata() */
331 : /************************************************************************/
332 :
333 0 : int PALSARJaxaDataset::GetGCPCount() {
334 0 : return nGCPCount;
335 : }
336 :
337 :
338 : /************************************************************************/
339 : /* GetGCPs() */
340 : /************************************************************************/
341 :
342 0 : const GDAL_GCP *PALSARJaxaDataset::GetGCPs() {
343 0 : return pasGCPList;
344 : }
345 :
346 :
347 : /************************************************************************/
348 : /* ReadMetadata() */
349 : /************************************************************************/
350 :
351 0 : void PALSARJaxaDataset::ReadMetadata( PALSARJaxaDataset *poDS, FILE *fp ) {
352 : /* seek to the end fo the leader file descriptor */
353 0 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH, SEEK_SET );
354 0 : if (poDS->nFileType == level_11) {
355 0 : poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.1" );
356 0 : poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" );
357 : }
358 : else {
359 0 : poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.5" );
360 : /* extract equivalent number of looks */
361 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
362 0 : EFFECTIVE_LOOKS_AZIMUTH_OFFSET, SEEK_SET );
363 : char pszENL[17];
364 : double dfENL;
365 0 : READ_CHAR_FLOAT(dfENL, 16, fp);
366 0 : sprintf( pszENL, "%-16.1f", dfENL );
367 0 : poDS->SetMetadataItem( "AZIMUTH_LOOKS", pszENL );
368 :
369 : /* extract pixel spacings */
370 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
371 0 : DATA_SET_SUMMARY_LENGTH + PIXEL_SPACING_OFFSET, SEEK_SET );
372 : double dfPixelSpacing;
373 : double dfLineSpacing;
374 : char pszPixelSpacing[33];
375 : char pszLineSpacing[33];
376 0 : READ_CHAR_FLOAT(dfPixelSpacing, 16, fp);
377 0 : READ_CHAR_FLOAT(dfLineSpacing, 16, fp);
378 0 : sprintf( pszPixelSpacing, "%-32.1f",dfPixelSpacing );
379 0 : sprintf( pszLineSpacing, "%-32.1f", dfLineSpacing );
380 0 : poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing );
381 0 : poDS->SetMetadataItem( "LINE_SPACING", pszPixelSpacing );
382 :
383 : /* Alphanumeric projection name */
384 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
385 : DATA_SET_SUMMARY_LENGTH + ALPHANUMERIC_PROJECTION_NAME_OFFSET,
386 0 : SEEK_SET );
387 : char pszProjName[33];
388 0 : READ_STRING(pszProjName, 32, fp);
389 0 : poDS->SetMetadataItem( "PROJECTION_NAME", pszProjName );
390 :
391 : /* Extract corner GCPs */
392 0 : poDS->nGCPCount = 4;
393 : poDS->pasGCPList = (GDAL_GCP *)CPLCalloc( sizeof(GDAL_GCP),
394 0 : poDS->nGCPCount );
395 0 : GDALInitGCPs( poDS->nGCPCount, poDS->pasGCPList );
396 :
397 : /* setup the GCPs */
398 : int i;
399 0 : for (i = 0; i < poDS->nGCPCount; i++) {
400 : char pszID[2];
401 0 : sprintf( pszID, "%d", i + 1);
402 0 : CPLFree(poDS->pasGCPList[i].pszId);
403 0 : poDS->pasGCPList[i].pszId = CPLStrdup( pszID );
404 0 : poDS->pasGCPList[i].dfGCPZ = 0.0;
405 : }
406 :
407 0 : double dfTemp = 0.0;
408 : /* seek to start of GCPs */
409 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
410 0 : DATA_SET_SUMMARY_LENGTH + TOP_LEFT_LAT_OFFSET, SEEK_SET );
411 :
412 : /* top-left GCP */
413 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
414 0 : poDS->pasGCPList[0].dfGCPY = dfTemp;
415 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
416 0 : poDS->pasGCPList[0].dfGCPX = dfTemp;
417 0 : poDS->pasGCPList[0].dfGCPLine = 0.5;
418 0 : poDS->pasGCPList[0].dfGCPPixel = 0.5;
419 :
420 : /* top right GCP */
421 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
422 0 : poDS->pasGCPList[1].dfGCPY = dfTemp;
423 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
424 0 : poDS->pasGCPList[1].dfGCPX = dfTemp;
425 0 : poDS->pasGCPList[1].dfGCPLine = 0.5;
426 0 : poDS->pasGCPList[1].dfGCPPixel = poDS->nRasterYSize - 0.5;
427 :
428 : /* bottom right GCP */
429 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
430 0 : poDS->pasGCPList[2].dfGCPY = dfTemp;
431 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
432 0 : poDS->pasGCPList[2].dfGCPX = dfTemp;
433 0 : poDS->pasGCPList[2].dfGCPLine = poDS->nRasterYSize - 0.5;
434 0 : poDS->pasGCPList[2].dfGCPPixel = poDS->nRasterYSize - 0.5;
435 :
436 : /* bottom left GCP */
437 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
438 0 : poDS->pasGCPList[3].dfGCPY = dfTemp;
439 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
440 0 : poDS->pasGCPList[3].dfGCPX = dfTemp;
441 0 : poDS->pasGCPList[3].dfGCPLine = poDS->nRasterYSize - 0.5;
442 0 : poDS->pasGCPList[3].dfGCPPixel = 0.5;
443 : }
444 :
445 : /* some generic metadata items */
446 0 : poDS->SetMetadataItem( "SENSOR_BAND", "L" ); /* PALSAR is L-band */
447 0 : poDS->SetMetadataItem( "RANGE_LOOKS", "1.0" );
448 :
449 : /* Check if this is a PolSAR dataset */
450 0 : if ( poDS->GetRasterCount() == 4 ) {
451 : /* PALSAR data is only available from JAXA in Scattering Matrix form */
452 0 : poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
453 : }
454 :
455 0 : }
456 :
457 : /************************************************************************/
458 : /* Identify() */
459 : /************************************************************************/
460 :
461 9942 : int PALSARJaxaDataset::Identify( GDALOpenInfo *poOpenInfo ) {
462 9942 : if ( poOpenInfo->fp == NULL || poOpenInfo->nHeaderBytes < 360 )
463 8920 : return 0;
464 :
465 : /* First, check that this is a PALSAR image indeed */
466 1022 : if ( !EQUALN((char *)(poOpenInfo->pabyHeader + 60),"AL", 2)
467 : || !EQUALN(CPLGetBasename((char *)(poOpenInfo->pszFilename)) + 4,
468 : "ALPSR", 5) )
469 : {
470 1022 : return 0;
471 : }
472 :
473 0 : FILE *fpL = VSIFOpenL( poOpenInfo->pszFilename, "r" );
474 0 : if( fpL == NULL )
475 0 : return FALSE;
476 :
477 : /* Check that this is a volume directory file */
478 0 : int nRecordSeq = 0;
479 0 : int nRecordSubtype = 0;
480 0 : int nRecordType = 0;
481 0 : int nSecondSubtype = 0;
482 0 : int nThirdSubtype = 0;
483 0 : int nLengthRecord = 0;
484 :
485 0 : VSIFSeekL(fpL, 0, SEEK_SET);
486 :
487 0 : READ_WORD(fpL, nRecordSeq);
488 0 : READ_BYTE(fpL, nRecordSubtype);
489 0 : READ_BYTE(fpL, nRecordType);
490 0 : READ_BYTE(fpL, nSecondSubtype);
491 0 : READ_BYTE(fpL, nThirdSubtype);
492 0 : READ_WORD(fpL, nLengthRecord);
493 :
494 0 : VSIFCloseL( fpL );
495 :
496 : /* Check that we have the right record */
497 0 : if ( nRecordSeq == 1 && nRecordSubtype == 192 && nRecordType == 192 &&
498 : nSecondSubtype == 18 && nThirdSubtype == 18 && nLengthRecord == 360 )
499 : {
500 0 : return 1;
501 : }
502 :
503 0 : return 0;
504 : }
505 :
506 : /************************************************************************/
507 : /* Open() */
508 : /************************************************************************/
509 2212 : GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) {
510 : /* Check that this actually is a JAXA PALSAR product */
511 2212 : if ( !PALSARJaxaDataset::Identify(poOpenInfo) )
512 2212 : return NULL;
513 :
514 : /* -------------------------------------------------------------------- */
515 : /* Confirm the requested access is supported. */
516 : /* -------------------------------------------------------------------- */
517 0 : if( poOpenInfo->eAccess == GA_Update )
518 : {
519 : CPLError( CE_Failure, CPLE_NotSupported,
520 : "The JAXAPALSAR driver does not support update access to existing"
521 0 : " datasets.\n" );
522 0 : return NULL;
523 : }
524 :
525 0 : PALSARJaxaDataset *poDS = new PALSARJaxaDataset();
526 :
527 : /* Get the suffix of the filename, we'll need this */
528 : char *pszSuffix = VSIStrdup( (char *)
529 0 : (CPLGetFilename( poOpenInfo->pszFilename ) + 3) );
530 :
531 : /* Try to read each of the polarizations */
532 : char *pszImgFile = (char *)VSIMalloc(
533 : strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
534 0 : strlen( pszSuffix ) + 8 );
535 :
536 0 : int nBandNum = 1;
537 :
538 : /* HH */
539 : FILE *fpHH;
540 : sprintf( pszImgFile, "%s%sIMG-HH%s",
541 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
542 0 : fpHH = VSIFOpenL( pszImgFile, "rb" );
543 0 : if (fpHH != NULL) {
544 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) );
545 0 : nBandNum++;
546 : }
547 :
548 : /* HV */
549 : FILE *fpHV;
550 : sprintf( pszImgFile, "%s%sIMG-HV%s",
551 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
552 0 : fpHV = VSIFOpenL( pszImgFile, "rb" );
553 0 : if (fpHV != NULL) {
554 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) );
555 0 : nBandNum++;
556 : }
557 :
558 : /* VH */
559 : FILE *fpVH;
560 : sprintf( pszImgFile, "%s%sIMG-VH%s",
561 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
562 0 : fpVH = VSIFOpenL( pszImgFile, "rb" );
563 0 : if (fpVH != NULL) {
564 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) );
565 0 : nBandNum++;
566 : }
567 :
568 : /* VV */
569 : FILE *fpVV;
570 : sprintf( pszImgFile, "%s%sIMG-VV%s",
571 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
572 0 : fpVV = VSIFOpenL( pszImgFile, "rb" );
573 0 : if (fpVV != NULL) {
574 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) );
575 0 : nBandNum++;
576 : }
577 :
578 0 : VSIFree( pszImgFile );
579 :
580 : /* did we get at least one band? */
581 0 : if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) {
582 : CPLError( CE_Failure, CPLE_AppDefined,
583 0 : "Unable to find any image data. Aborting opening as PALSAR image.");
584 0 : delete poDS;
585 0 : return NULL;
586 : }
587 :
588 : /* read metadata from Leader file. */
589 : char *pszLeaderFilename = (char *)VSIMalloc(
590 : strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
591 0 : strlen(pszSuffix) + 5 );
592 : sprintf( pszLeaderFilename, "%s%sLED%s",
593 0 : CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix );
594 :
595 0 : FILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" );
596 : /* check if the leader is actually present */
597 0 : if (fpLeader != NULL) {
598 0 : ReadMetadata(poDS, fpLeader);
599 0 : VSIFCloseL(fpLeader);
600 : }
601 :
602 0 : VSIFree(pszLeaderFilename);
603 :
604 0 : VSIFree( pszSuffix );
605 :
606 : /* -------------------------------------------------------------------- */
607 : /* Initialize any PAM information. */
608 : /* -------------------------------------------------------------------- */
609 0 : poDS->SetDescription( poOpenInfo->pszFilename );
610 0 : poDS->TryLoadXML();
611 :
612 : /* -------------------------------------------------------------------- */
613 : /* Check for overviews. */
614 : /* -------------------------------------------------------------------- */
615 0 : poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
616 :
617 0 : return poDS;
618 : }
619 :
620 : /************************************************************************/
621 : /* GDALRegister_PALSARJaxa() */
622 : /************************************************************************/
623 :
624 338 : void GDALRegister_PALSARJaxa() {
625 : GDALDriver *poDriver;
626 :
627 338 : if( GDALGetDriverByName( "JAXAPALSAR" ) == NULL ) {
628 336 : poDriver = new GDALDriver();
629 336 : poDriver->SetDescription( "JAXAPALSAR" );
630 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
631 336 : "JAXA PALSAR Product Reader (Level 1.1/1.5)" );
632 : poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
633 336 : "frmt_palsar.html" );
634 336 : poDriver->pfnOpen = PALSARJaxaDataset::Open;
635 336 : poDriver->pfnIdentify = PALSARJaxaDataset::Identify;
636 336 : GetGDALDriverManager()->RegisterDriver( poDriver );
637 : }
638 338 : }
|