1 : /******************************************************************************
2 : * $Id: jaxapalsardataset.cpp 22636 2011-07-03 10:39:11Z 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 22636 2011-07-03 10:39:11Z 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 : level_10
143 : };
144 :
145 : enum ePolarization {
146 : hh = 0,
147 : hv,
148 : vh,
149 : vv
150 : };
151 :
152 : /************************************************************************/
153 : /* ==================================================================== */
154 : /* PALSARJaxaDataset */
155 : /* ==================================================================== */
156 : /************************************************************************/
157 :
158 : class PALSARJaxaRasterBand;
159 :
160 : class PALSARJaxaDataset : public GDALPamDataset {
161 : friend class PALSARJaxaRasterBand;
162 : private:
163 : GDAL_GCP *pasGCPList;
164 : int nGCPCount;
165 : eFileType nFileType;
166 : public:
167 : PALSARJaxaDataset();
168 : ~PALSARJaxaDataset();
169 :
170 : int GetGCPCount();
171 : const GDAL_GCP *GetGCPs();
172 :
173 : static GDALDataset *Open( GDALOpenInfo *poOpenInfo );
174 : static int Identify( GDALOpenInfo *poOpenInfo );
175 : static void ReadMetadata( PALSARJaxaDataset *poDS, VSILFILE *fp );
176 : };
177 :
178 0 : PALSARJaxaDataset::PALSARJaxaDataset()
179 : {
180 0 : pasGCPList = NULL;
181 0 : nGCPCount = 0;
182 0 : }
183 :
184 0 : PALSARJaxaDataset::~PALSARJaxaDataset()
185 : {
186 0 : if( nGCPCount > 0 )
187 : {
188 0 : GDALDeinitGCPs( nGCPCount, pasGCPList );
189 0 : CPLFree( pasGCPList );
190 : }
191 0 : }
192 :
193 : /************************************************************************/
194 : /* ==================================================================== */
195 : /* PALSARJaxaRasterBand */
196 : /* ==================================================================== */
197 : /************************************************************************/
198 :
199 : class PALSARJaxaRasterBand : public GDALRasterBand {
200 : VSILFILE *fp;
201 : int nRasterXSize;
202 : int nRasterYSize;
203 : ePolarization nPolarization;
204 : eFileType nFileType;
205 : int nBitsPerSample;
206 : int nSamplesPerGroup;
207 : int nRecordSize;
208 : public:
209 : PALSARJaxaRasterBand( PALSARJaxaDataset *poDS, int nBand, VSILFILE *fp );
210 : ~PALSARJaxaRasterBand();
211 :
212 : CPLErr IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage );
213 : };
214 :
215 : /************************************************************************/
216 : /* PALSARJaxaRasterBand() */
217 : /************************************************************************/
218 :
219 0 : PALSARJaxaRasterBand::PALSARJaxaRasterBand( PALSARJaxaDataset *poDS,
220 0 : int nBand, VSILFILE *fp )
221 : {
222 0 : this->fp = fp;
223 :
224 : /* Read image options record to determine the type of data */
225 0 : VSIFSeekL( fp, BITS_PER_SAMPLE_OFFSET, SEEK_SET );
226 0 : nBitsPerSample = 0;
227 0 : nSamplesPerGroup = 0;
228 0 : READ_CHAR_VAL( nBitsPerSample, BITS_PER_SAMPLE_LENGTH, fp );
229 0 : READ_CHAR_VAL( nSamplesPerGroup, SAMPLES_PER_GROUP_LENGTH, fp );
230 :
231 0 : if (nBitsPerSample == 32 && nSamplesPerGroup == 2) {
232 0 : eDataType = GDT_CFloat32;
233 0 : nFileType = level_11;
234 : }
235 0 : else if (nBitsPerSample == 8 && nSamplesPerGroup == 2) {
236 0 : eDataType = GDT_CInt16; /* shuold be 2 x signed byte */
237 0 : nFileType = level_10;
238 : }
239 : else {
240 0 : eDataType = GDT_UInt16;
241 0 : nFileType = level_15;
242 : }
243 :
244 0 : poDS->nFileType = nFileType;
245 :
246 : /* Read number of range/azimuth lines */
247 0 : VSIFSeekL( fp, NUMBER_LINES_OFFSET, SEEK_SET );
248 0 : READ_CHAR_VAL( nRasterYSize, NUMBER_LINES_LENGTH, fp );
249 0 : VSIFSeekL( fp, SAR_DATA_RECORD_LENGTH_OFFSET, SEEK_SET );
250 0 : READ_CHAR_VAL( nRecordSize, SAR_DATA_RECORD_LENGTH_LENGTH, fp );
251 : nRasterXSize = (nRecordSize -
252 : (nFileType != level_15 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET))
253 0 : / ((nBitsPerSample / 8) * nSamplesPerGroup);
254 :
255 0 : poDS->nRasterXSize = nRasterXSize;
256 0 : poDS->nRasterYSize = nRasterYSize;
257 :
258 : /* Polarization */
259 0 : switch (nBand) {
260 : case 0:
261 0 : nPolarization = hh;
262 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "HH" );
263 0 : break;
264 : case 1:
265 0 : nPolarization = hv;
266 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "HV" );
267 0 : break;
268 : case 2:
269 0 : nPolarization = vh;
270 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "VH" );
271 0 : break;
272 : case 3:
273 0 : nPolarization = vv;
274 0 : SetMetadataItem( "POLARIMETRIC_INTERP", "VV" );
275 : break;
276 : }
277 :
278 : /* size of block we can read */
279 0 : nBlockXSize = nRasterXSize;
280 0 : nBlockYSize = 1;
281 :
282 : /* set the file pointer to the first SAR data record */
283 0 : VSIFSeekL( fp, IMAGE_OPT_DESC_LENGTH, SEEK_SET );
284 0 : }
285 :
286 : /************************************************************************/
287 : /* ~PALSARJaxaRasterBand() */
288 : /************************************************************************/
289 :
290 0 : PALSARJaxaRasterBand::~PALSARJaxaRasterBand()
291 : {
292 0 : if (fp)
293 0 : VSIFCloseL(fp);
294 0 : }
295 :
296 : /************************************************************************/
297 : /* IReadBlock() */
298 : /************************************************************************/
299 :
300 0 : CPLErr PALSARJaxaRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
301 : void *pImage )
302 : {
303 0 : int nNumBytes = 0;
304 0 : if (nFileType == level_11) {
305 0 : nNumBytes = 8;
306 : }
307 : else {
308 0 : nNumBytes = 2;
309 : }
310 :
311 : int nOffset = IMAGE_OPT_DESC_LENGTH + ((nBlockYOff - 1) * nRecordSize) +
312 0 : (nFileType == level_11 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET);
313 :
314 0 : VSIFSeekL( fp, nOffset, SEEK_SET );
315 0 : VSIFReadL( pImage, nNumBytes, nRasterXSize, fp );
316 :
317 : #ifdef CPL_LSB
318 0 : if (nFileType == level_11)
319 0 : GDALSwapWords( pImage, 4, nBlockXSize * 2, 4 );
320 : else
321 0 : GDALSwapWords( pImage, 2, nBlockXSize, 2 );
322 : #endif
323 :
324 0 : return CE_None;
325 : }
326 :
327 :
328 : /************************************************************************/
329 : /* ==================================================================== */
330 : /* PALSARJaxaDataset */
331 : /* ==================================================================== */
332 : /************************************************************************/
333 :
334 : /************************************************************************/
335 : /* ReadMetadata() */
336 : /************************************************************************/
337 :
338 0 : int PALSARJaxaDataset::GetGCPCount() {
339 0 : return nGCPCount;
340 : }
341 :
342 :
343 : /************************************************************************/
344 : /* GetGCPs() */
345 : /************************************************************************/
346 :
347 0 : const GDAL_GCP *PALSARJaxaDataset::GetGCPs() {
348 0 : return pasGCPList;
349 : }
350 :
351 :
352 : /************************************************************************/
353 : /* ReadMetadata() */
354 : /************************************************************************/
355 :
356 0 : void PALSARJaxaDataset::ReadMetadata( PALSARJaxaDataset *poDS, VSILFILE *fp ) {
357 : /* seek to the end fo the leader file descriptor */
358 0 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH, SEEK_SET );
359 0 : if (poDS->nFileType == level_10) {
360 0 : poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.0" );
361 0 : poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" );
362 : }
363 0 : else if (poDS->nFileType == level_11) {
364 0 : poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.1" );
365 0 : poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" );
366 : }
367 : else {
368 0 : poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.5" );
369 : /* extract equivalent number of looks */
370 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
371 0 : EFFECTIVE_LOOKS_AZIMUTH_OFFSET, SEEK_SET );
372 : char pszENL[17];
373 : double dfENL;
374 0 : READ_CHAR_FLOAT(dfENL, 16, fp);
375 0 : sprintf( pszENL, "%-16.1f", dfENL );
376 0 : poDS->SetMetadataItem( "AZIMUTH_LOOKS", pszENL );
377 :
378 : /* extract pixel spacings */
379 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
380 0 : DATA_SET_SUMMARY_LENGTH + PIXEL_SPACING_OFFSET, SEEK_SET );
381 : double dfPixelSpacing;
382 : double dfLineSpacing;
383 : char pszPixelSpacing[33];
384 : char pszLineSpacing[33];
385 0 : READ_CHAR_FLOAT(dfPixelSpacing, 16, fp);
386 0 : READ_CHAR_FLOAT(dfLineSpacing, 16, fp);
387 0 : sprintf( pszPixelSpacing, "%-32.1f",dfPixelSpacing );
388 0 : sprintf( pszLineSpacing, "%-32.1f", dfLineSpacing );
389 0 : poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing );
390 0 : poDS->SetMetadataItem( "LINE_SPACING", pszPixelSpacing );
391 :
392 : /* Alphanumeric projection name */
393 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
394 : DATA_SET_SUMMARY_LENGTH + ALPHANUMERIC_PROJECTION_NAME_OFFSET,
395 0 : SEEK_SET );
396 : char pszProjName[33];
397 0 : READ_STRING(pszProjName, 32, fp);
398 0 : poDS->SetMetadataItem( "PROJECTION_NAME", pszProjName );
399 :
400 : /* Extract corner GCPs */
401 0 : poDS->nGCPCount = 4;
402 : poDS->pasGCPList = (GDAL_GCP *)CPLCalloc( sizeof(GDAL_GCP),
403 0 : poDS->nGCPCount );
404 0 : GDALInitGCPs( poDS->nGCPCount, poDS->pasGCPList );
405 :
406 : /* setup the GCPs */
407 : int i;
408 0 : for (i = 0; i < poDS->nGCPCount; i++) {
409 : char pszID[2];
410 0 : sprintf( pszID, "%d", i + 1);
411 0 : CPLFree(poDS->pasGCPList[i].pszId);
412 0 : poDS->pasGCPList[i].pszId = CPLStrdup( pszID );
413 0 : poDS->pasGCPList[i].dfGCPZ = 0.0;
414 : }
415 :
416 0 : double dfTemp = 0.0;
417 : /* seek to start of GCPs */
418 : VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH +
419 0 : DATA_SET_SUMMARY_LENGTH + TOP_LEFT_LAT_OFFSET, SEEK_SET );
420 :
421 : /* top-left GCP */
422 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
423 0 : poDS->pasGCPList[0].dfGCPY = dfTemp;
424 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
425 0 : poDS->pasGCPList[0].dfGCPX = dfTemp;
426 0 : poDS->pasGCPList[0].dfGCPLine = 0.5;
427 0 : poDS->pasGCPList[0].dfGCPPixel = 0.5;
428 :
429 : /* top right GCP */
430 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
431 0 : poDS->pasGCPList[1].dfGCPY = dfTemp;
432 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
433 0 : poDS->pasGCPList[1].dfGCPX = dfTemp;
434 0 : poDS->pasGCPList[1].dfGCPLine = 0.5;
435 0 : poDS->pasGCPList[1].dfGCPPixel = poDS->nRasterYSize - 0.5;
436 :
437 : /* bottom right GCP */
438 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
439 0 : poDS->pasGCPList[2].dfGCPY = dfTemp;
440 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
441 0 : poDS->pasGCPList[2].dfGCPX = dfTemp;
442 0 : poDS->pasGCPList[2].dfGCPLine = poDS->nRasterYSize - 0.5;
443 0 : poDS->pasGCPList[2].dfGCPPixel = poDS->nRasterYSize - 0.5;
444 :
445 : /* bottom left GCP */
446 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
447 0 : poDS->pasGCPList[3].dfGCPY = dfTemp;
448 0 : READ_CHAR_FLOAT(dfTemp, 16, fp);
449 0 : poDS->pasGCPList[3].dfGCPX = dfTemp;
450 0 : poDS->pasGCPList[3].dfGCPLine = poDS->nRasterYSize - 0.5;
451 0 : poDS->pasGCPList[3].dfGCPPixel = 0.5;
452 : }
453 :
454 : /* some generic metadata items */
455 0 : poDS->SetMetadataItem( "SENSOR_BAND", "L" ); /* PALSAR is L-band */
456 0 : poDS->SetMetadataItem( "RANGE_LOOKS", "1.0" );
457 :
458 : /* Check if this is a PolSAR dataset */
459 0 : if ( poDS->GetRasterCount() == 4 ) {
460 : /* PALSAR data is only available from JAXA in Scattering Matrix form */
461 0 : poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
462 : }
463 :
464 0 : }
465 :
466 : /************************************************************************/
467 : /* Identify() */
468 : /************************************************************************/
469 :
470 26876 : int PALSARJaxaDataset::Identify( GDALOpenInfo *poOpenInfo ) {
471 26876 : if ( poOpenInfo->nHeaderBytes < 360 )
472 22950 : return 0;
473 :
474 : /* First, check that this is a PALSAR image indeed */
475 3926 : if ( !EQUALN((char *)(poOpenInfo->pabyHeader + 60),"AL", 2)
476 : || !EQUALN(CPLGetBasename((char *)(poOpenInfo->pszFilename)) + 4,
477 : "ALPSR", 5) )
478 : {
479 3926 : return 0;
480 : }
481 :
482 0 : VSILFILE *fpL = VSIFOpenL( poOpenInfo->pszFilename, "r" );
483 0 : if( fpL == NULL )
484 0 : return FALSE;
485 :
486 : /* Check that this is a volume directory file */
487 0 : int nRecordSeq = 0;
488 0 : int nRecordSubtype = 0;
489 0 : int nRecordType = 0;
490 0 : int nSecondSubtype = 0;
491 0 : int nThirdSubtype = 0;
492 0 : int nLengthRecord = 0;
493 :
494 0 : VSIFSeekL(fpL, 0, SEEK_SET);
495 :
496 0 : READ_WORD(fpL, nRecordSeq);
497 0 : READ_BYTE(fpL, nRecordSubtype);
498 0 : READ_BYTE(fpL, nRecordType);
499 0 : READ_BYTE(fpL, nSecondSubtype);
500 0 : READ_BYTE(fpL, nThirdSubtype);
501 0 : READ_WORD(fpL, nLengthRecord);
502 :
503 0 : VSIFCloseL( fpL );
504 :
505 : /* Check that we have the right record */
506 0 : if ( nRecordSeq == 1 && nRecordSubtype == 192 && nRecordType == 192 &&
507 : nSecondSubtype == 18 && nThirdSubtype == 18 && nLengthRecord == 360 )
508 : {
509 0 : return 1;
510 : }
511 :
512 0 : return 0;
513 : }
514 :
515 : /************************************************************************/
516 : /* Open() */
517 : /************************************************************************/
518 7852 : GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) {
519 : /* Check that this actually is a JAXA PALSAR product */
520 7852 : if ( !PALSARJaxaDataset::Identify(poOpenInfo) )
521 7852 : return NULL;
522 :
523 : /* -------------------------------------------------------------------- */
524 : /* Confirm the requested access is supported. */
525 : /* -------------------------------------------------------------------- */
526 0 : if( poOpenInfo->eAccess == GA_Update )
527 : {
528 : CPLError( CE_Failure, CPLE_NotSupported,
529 : "The JAXAPALSAR driver does not support update access to existing"
530 0 : " datasets.\n" );
531 0 : return NULL;
532 : }
533 :
534 0 : PALSARJaxaDataset *poDS = new PALSARJaxaDataset();
535 :
536 : /* Get the suffix of the filename, we'll need this */
537 : char *pszSuffix = VSIStrdup( (char *)
538 0 : (CPLGetFilename( poOpenInfo->pszFilename ) + 3) );
539 :
540 : /* Try to read each of the polarizations */
541 : char *pszImgFile = (char *)VSIMalloc(
542 : strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
543 0 : strlen( pszSuffix ) + 8 );
544 :
545 0 : int nBandNum = 1;
546 :
547 : /* HH */
548 : VSILFILE *fpHH;
549 : sprintf( pszImgFile, "%s%sIMG-HH%s",
550 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
551 0 : fpHH = VSIFOpenL( pszImgFile, "rb" );
552 0 : if (fpHH != NULL) {
553 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) );
554 0 : nBandNum++;
555 : }
556 :
557 : /* HV */
558 : VSILFILE *fpHV;
559 : sprintf( pszImgFile, "%s%sIMG-HV%s",
560 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
561 0 : fpHV = VSIFOpenL( pszImgFile, "rb" );
562 0 : if (fpHV != NULL) {
563 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) );
564 0 : nBandNum++;
565 : }
566 :
567 : /* VH */
568 : VSILFILE *fpVH;
569 : sprintf( pszImgFile, "%s%sIMG-VH%s",
570 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
571 0 : fpVH = VSIFOpenL( pszImgFile, "rb" );
572 0 : if (fpVH != NULL) {
573 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) );
574 0 : nBandNum++;
575 : }
576 :
577 : /* VV */
578 : VSILFILE *fpVV;
579 : sprintf( pszImgFile, "%s%sIMG-VV%s",
580 0 : CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
581 0 : fpVV = VSIFOpenL( pszImgFile, "rb" );
582 0 : if (fpVV != NULL) {
583 0 : poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) );
584 0 : nBandNum++;
585 : }
586 :
587 0 : VSIFree( pszImgFile );
588 :
589 : /* did we get at least one band? */
590 0 : if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) {
591 : CPLError( CE_Failure, CPLE_AppDefined,
592 0 : "Unable to find any image data. Aborting opening as PALSAR image.");
593 0 : delete poDS;
594 0 : VSIFree( pszSuffix );
595 0 : return NULL;
596 : }
597 :
598 : /* Level 1.0 products are not supported */
599 0 : if (poDS->nFileType == level_10) {
600 : CPLError( CE_Failure, CPLE_AppDefined,
601 0 : "ALOS PALSAR Level 1.0 products are not supported. Aborting opening as PALSAR image.");
602 0 : delete poDS;
603 0 : VSIFree( pszSuffix );
604 0 : return NULL;
605 : }
606 :
607 : /* read metadata from Leader file. */
608 : char *pszLeaderFilename = (char *)VSIMalloc(
609 : strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
610 0 : strlen(pszSuffix) + 5 );
611 : sprintf( pszLeaderFilename, "%s%sLED%s",
612 0 : CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix );
613 :
614 0 : VSILFILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" );
615 : /* check if the leader is actually present */
616 0 : if (fpLeader != NULL) {
617 0 : ReadMetadata(poDS, fpLeader);
618 0 : VSIFCloseL(fpLeader);
619 : }
620 :
621 0 : VSIFree(pszLeaderFilename);
622 :
623 0 : VSIFree( pszSuffix );
624 :
625 : /* -------------------------------------------------------------------- */
626 : /* Initialize any PAM information. */
627 : /* -------------------------------------------------------------------- */
628 0 : poDS->SetDescription( poOpenInfo->pszFilename );
629 0 : poDS->TryLoadXML();
630 :
631 : /* -------------------------------------------------------------------- */
632 : /* Check for overviews. */
633 : /* -------------------------------------------------------------------- */
634 0 : poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
635 :
636 0 : return poDS;
637 : }
638 :
639 : /************************************************************************/
640 : /* GDALRegister_PALSARJaxa() */
641 : /************************************************************************/
642 :
643 1135 : void GDALRegister_PALSARJaxa() {
644 : GDALDriver *poDriver;
645 :
646 1135 : if( GDALGetDriverByName( "JAXAPALSAR" ) == NULL ) {
647 1093 : poDriver = new GDALDriver();
648 1093 : poDriver->SetDescription( "JAXAPALSAR" );
649 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
650 1093 : "JAXA PALSAR Product Reader (Level 1.1/1.5)" );
651 : poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
652 1093 : "frmt_palsar.html" );
653 1093 : poDriver->pfnOpen = PALSARJaxaDataset::Open;
654 1093 : poDriver->pfnIdentify = PALSARJaxaDataset::Identify;
655 1093 : poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
656 :
657 1093 : GetGDALDriverManager()->RegisterDriver( poDriver );
658 : }
659 1135 : }
|