int EnvisatFile_SetKeyValueAsInt( EnvisatFile *self, 
                                  EnvisatFile_HeaderFlag mph_or_sph,
                                  const char *key,
                                  int value )

{
    char format[32], string_value[128];
    const char *prototype_value;


    prototype_value = EnvisatFile_GetKeyValueAsString( self, mph_or_sph, key, NULL);
    if( prototype_value == NULL )
    {
        char	error_buf[2048];

        sprintf( error_buf, 
                 "Unable to set header field \"%s\", field not found.", 
                 key );

        SendError( error_buf );
        return FAILURE;
    }

    sprintf( format, "%%+0%dd", (int) strlen(prototype_value) );
    sprintf( string_value, format, value );

    return EnvisatFile_SetKeyValueAsString( self, mph_or_sph, key, string_value );
}
int EnvisatFile_SetKeyValueAsDouble( EnvisatFile *self, 
                                     EnvisatFile_HeaderFlag mph_or_sph,
                                     const char *key,
                                     double value )

{
    char format[32], string_value[128];
    const char *prototype_value;
    int		length;

    prototype_value = EnvisatFile_GetKeyValueAsString( self, mph_or_sph, key, NULL);
    if( prototype_value == NULL )
    {
        char	error_buf[2048];

        sprintf( error_buf, 
                 "Unable to set header field \"%s\", field not found.", 
                 key );

        SendError( error_buf );
        return FAILURE;
    }

    length = strlen(prototype_value);
    if( prototype_value[length-4] == 'E' )
    {
        sprintf( format, "%%+%dE", length-4 );
        sprintf( string_value, format, value );
    }
    else
    {
        int	decimals = 0, i;
        for( i = length-1; i > 0; i-- )
        {
            if( prototype_value[i] == '.' )
                break;
            
            decimals++;
        }

        sprintf( format, "%%+0%d.%df", length, decimals );
        sprintf( string_value, format, value );

        if( (int)strlen(string_value) > length )
            string_value[length] = '\0';
    }

    return EnvisatFile_SetKeyValueAsString( self, mph_or_sph, key, string_value );
}
Beispiel #3
0
void EnvisatDataset::CollectMetadata( EnvisatFile_HeaderFlag  eMPHOrSPH )

{
    int		iKey;

    for( iKey = 0; TRUE; iKey++ )
    {
        const char *pszValue, *pszKey;
        char  szHeaderKey[128];

        pszKey = EnvisatFile_GetKeyByIndex(hEnvisatFile, eMPHOrSPH, iKey);
        if( pszKey == NULL )
            break;

        pszValue = EnvisatFile_GetKeyValueAsString( hEnvisatFile, eMPHOrSPH,
                                                    pszKey, NULL );

        if( pszValue == NULL )
            continue;

        // skip some uninteresting structural information.
        if( EQUAL(pszKey,"TOT_SIZE")
            || EQUAL(pszKey,"SPH_SIZE")
            || EQUAL(pszKey,"NUM_DSD")
            || EQUAL(pszKey,"DSD_SIZE")
            || EQUAL(pszKey,"NUM_DATA_SETS") )
            continue;

        if( eMPHOrSPH == MPH )
            sprintf( szHeaderKey, "MPH_%s", pszKey );
        else
            sprintf( szHeaderKey, "SPH_%s", pszKey );

        SetMetadataItem( szHeaderKey, pszValue );
    }
}
Beispiel #4
0
GDALDataset *EnvisatDataset::Open( GDALOpenInfo * poOpenInfo )

{
    EnvisatFile	*hEnvisatFile;

/* -------------------------------------------------------------------- */
/*      Check the header.                                               */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 8 )
        return NULL;

    if( !EQUALN((const char *) poOpenInfo->pabyHeader, "PRODUCT=",8) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Try opening the dataset.                                        */
/* -------------------------------------------------------------------- */
    int		ds_index;

    if( EnvisatFile_Open( &hEnvisatFile, poOpenInfo->pszFilename, "r" )
        == FAILURE )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Find a Mesurement type dataset to use as our reference          */
/*      raster band.                                                    */
/* -------------------------------------------------------------------- */
    int		dsr_size, num_dsr, ds_offset, bNative;
    char        *pszDSType;

    for( ds_index = 0; TRUE; ds_index++ )
    {
        if( EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index,
                                        NULL, &pszDSType, NULL,
                                        &ds_offset, NULL,
                                        &num_dsr, &dsr_size ) == FAILURE )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Unable to find \"MDS1\" measurement datatset in Envisat file." );
            EnvisatFile_Close( hEnvisatFile );
            return NULL;
        }

        /* Have we found what we are looking for?  A Measurement ds. */
        if( EQUAL(pszDSType,"M") )
            break;
    }

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        EnvisatFile_Close( hEnvisatFile );
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The ENVISAT driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    EnvisatDataset 	*poDS;

    poDS = new EnvisatDataset();

    poDS->hEnvisatFile = hEnvisatFile;

/* -------------------------------------------------------------------- */
/*      Setup image definition.                                         */
/* -------------------------------------------------------------------- */
    const char  *pszDataType, *pszSampleType, *pszProduct;
    GDALDataType eDataType;
    int          nPrefixBytes;

    EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index,
                                NULL, NULL, NULL, &ds_offset, NULL,
                                &num_dsr, &dsr_size );

    poDS->nRasterXSize = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH,
                                                       "LINE_LENGTH", 0 );
    poDS->nRasterYSize = num_dsr;
    poDS->eAccess = GA_ReadOnly;

    pszProduct = EnvisatFile_GetKeyValueAsString( hEnvisatFile, MPH,
                                                  "PRODUCT", "" );
    pszDataType = EnvisatFile_GetKeyValueAsString( hEnvisatFile, SPH,
                                                   "DATA_TYPE", "" );
    pszSampleType = EnvisatFile_GetKeyValueAsString( hEnvisatFile, SPH,
                                                     "SAMPLE_TYPE", "" );
    if( EQUAL(pszDataType,"FLT32") && EQUALN(pszSampleType,"COMPLEX",7))
        eDataType = GDT_CFloat32;
    else if( EQUAL(pszDataType,"FLT32") )
        eDataType = GDT_Float32;
    else if( EQUAL(pszDataType,"UWORD") )
        eDataType = GDT_UInt16;
    else if( EQUAL(pszDataType,"SWORD") && EQUALN(pszSampleType,"COMPLEX",7) )
        eDataType = GDT_CInt16;
    else if( EQUAL(pszDataType,"SWORD") )
        eDataType = GDT_Int16;
    else if( EQUALN(pszProduct,"ATS_TOA_1",8) )
    {
        /* all 16bit data, no line length provided */
        eDataType = GDT_Int16;
        poDS->nRasterXSize = (dsr_size - 20) / 2;
    }
    else if( poDS->nRasterXSize == 0 )
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Envisat product format not recognised.  Assuming 8bit\n"
                  "with no per-record prefix data.  Results may be useless!" );
        eDataType = GDT_Byte;
        poDS->nRasterXSize = dsr_size;
    }
    else
    {
        if( dsr_size >= 2 * poDS->nRasterXSize )
            eDataType = GDT_UInt16;
        else
            eDataType = GDT_Byte;
    }

#ifdef CPL_LSB
    bNative = FALSE;
#else
    bNative = TRUE;
#endif

    nPrefixBytes = dsr_size -
        ((GDALGetDataTypeSize(eDataType) / 8) * poDS->nRasterXSize);

/* -------------------------------------------------------------------- */
/*      Fail out if we didn't get non-zero sizes.                       */
/* -------------------------------------------------------------------- */
    if( poDS->nRasterXSize < 1 || poDS->nRasterYSize < 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unable to determine organization of dataset.  It would\n"
                  "appear this is an Envisat dataset, but an unsupported\n"
                  "data product.  Unable to utilize." );
        delete poDS;
        return NULL;
    }

    poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    if( poDS->fpImage == NULL )
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try to collect GCPs.                                            */
/* -------------------------------------------------------------------- */

/* -------------------------------------------------------------------- */
/*      Scan for all datasets matching the reference dataset.           */
/* -------------------------------------------------------------------- */
    int num_dsr2, dsr_size2, iBand = 0;
    const char *pszDSName;
    char szBandName[128];
    bool bMiltiChannel;

    for( ds_index = 0;
         EnvisatFile_GetDatasetInfo( hEnvisatFile, ds_index,
                                     (char **) &pszDSName, NULL, NULL,
                                     &ds_offset, NULL,
                                     &num_dsr2, &dsr_size2 ) == SUCCESS;
         ds_index++ )
    {
        if( !EQUAL(pszDSType,"M") || num_dsr2 != num_dsr )
            continue;

        if( EQUALN(pszProduct,"MER",3) && (pszProduct[8] == '2') &&
            ( (strstr(pszDSName, "MDS(16)") != NULL) ||
              (strstr(pszDSName, "MDS(19)") != NULL)) )
            bMiltiChannel = true;
        else
            bMiltiChannel = false;

        if( (dsr_size2 == dsr_size) && !bMiltiChannel )
        {
            poDS->SetBand( iBand+1,
                       new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                                          ds_offset + nPrefixBytes,
                                          GDALGetDataTypeSize(eDataType) / 8,
                                          dsr_size,
                                          eDataType, bNative, TRUE ) );
            iBand++;

            poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
        }
/* -------------------------------------------------------------------- */
/*       Handle MERIS Level 2 datasets with data type different from    */
/*       the one declared in the SPH                                    */
/* -------------------------------------------------------------------- */
        else if( EQUALN(pszProduct,"MER",3) &&
                 (strstr(pszDSName, "Flags") != NULL) )
        {
            if (pszProduct[8] == '1')
            {
                // Flags
                poDS->SetBand( iBand+1,
                           new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                                              ds_offset + nPrefixBytes, 3,
                                              dsr_size, GDT_Byte, bNative, TRUE ) );
                iBand++;

                poDS->GetRasterBand(iBand)->SetDescription( pszDSName );

                // Detector indices
                poDS->SetBand( iBand+1,
                           new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                                              ds_offset + nPrefixBytes + 1,
                                              3, dsr_size, GDT_Int16,
                                              bNative, TRUE ) );
                iBand++;

                const char *pszSuffix = strstr( pszDSName, "MDS" );
                if ( pszSuffix != NULL)
                    sprintf( szBandName, "Detector index %s", pszSuffix );
                else
                    sprintf( szBandName, "Detector index" );
                poDS->GetRasterBand(iBand)->SetDescription( szBandName );
            }
            else if ( (pszProduct[8] == '2') &&
                      (dsr_size2 >= 3 * poDS->nRasterXSize ) )
            {
                int nFlagPrefixBytes = dsr_size2 - 3 * poDS->nRasterXSize;

                poDS->SetBand( iBand+1,
                       new MerisL2FlagBand( poDS, iBand+1, poDS->fpImage,
                                            ds_offset, nFlagPrefixBytes ) );
                iBand++;

                poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
            }
        }
        else if( EQUALN(pszProduct,"MER",3) && (pszProduct[8] == '2') )
        {
            int nPrefixBytes2, nSubBands, nSubBandIdx, nSubBandOffset;

            int nPixelSize = 1;
            GDALDataType eDataType2 = GDT_Byte;

            nSubBands = dsr_size2 / poDS->nRasterXSize;
            if( (nSubBands < 1) || (nSubBands > 3) )
                nSubBands = 0;

            nPrefixBytes2 = dsr_size2 -
                (nSubBands * nPixelSize * poDS->nRasterXSize);

            for (nSubBandIdx = 0; nSubBandIdx < nSubBands; ++nSubBandIdx)
            {
                nSubBandOffset =
                    ds_offset + nPrefixBytes2 + nSubBandIdx * nPixelSize;
                poDS->SetBand( iBand+1,
                        new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                                           nSubBandOffset,
                                           nPixelSize * nSubBands,
                                           dsr_size2, eDataType2, bNative, TRUE ) );
                iBand++;

                if (nSubBands > 1)
                {
                    sprintf( szBandName, "%s (%d)", pszDSName, nSubBandIdx );
                    poDS->GetRasterBand(iBand)->SetDescription( szBandName );
                }
                else
                    poDS->GetRasterBand(iBand)->SetDescription( pszDSName );
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Collect metadata.                                               */
/* -------------------------------------------------------------------- */
    poDS->CollectMetadata( MPH );
    poDS->CollectMetadata( SPH );
    poDS->CollectDSDMetadata();
    poDS->CollectADSMetadata();

    if( EQUALN(pszProduct,"MER",3) )
        poDS->ScanForGCPs_MERIS();
    else
        poDS->ScanForGCPs_ASAR();

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
Beispiel #5
0
void EnvisatDataset::CollectADSMetadata()
{
    int nDSIndex, nNumDsr, nDSRSize;
    int nRecord;
    const char *pszDSName, *pszDSType, *pszDSFilename;
    const char *pszProduct;
    char *pszRecord;
    char szPrefix[128], szKey[128], szValue[1024];
    int i;
    CPLErr ret;
    const EnvisatRecordDescr *pRecordDescr = NULL;
    const EnvisatFieldDescr *pField;

    pszProduct = EnvisatFile_GetKeyValueAsString( hEnvisatFile, MPH,
                                                  "PRODUCT", "" );

    for( nDSIndex = 0;
         EnvisatFile_GetDatasetInfo( hEnvisatFile, nDSIndex,
                                     (char **) &pszDSName,
                                     (char **) &pszDSType,
                                     (char **) &pszDSFilename,
                                     NULL, NULL,
                                     &nNumDsr, &nDSRSize ) == SUCCESS;
         ++nDSIndex )
    {
        if( EQUALN(pszDSFilename,"NOT USED",8) || (nNumDsr <= 0) )
            continue;
        if( !EQUAL(pszDSType,"A") && !EQUAL(pszDSType,"G") )
            continue;

        for ( nRecord = 0; nRecord < nNumDsr; ++nRecord )
        {
            strncpy( szPrefix, pszDSName, sizeof(szPrefix) - 1);
            szPrefix[sizeof(szPrefix) - 1] = '\0';

            // strip trailing spaces
            for( i = strlen(szPrefix)-1; i && szPrefix[i] == ' '; --i )
                szPrefix[i] = '\0';

            // convert spaces into underscores
            for( i = 0; szPrefix[i] != '\0'; i++ )
            {
                if( szPrefix[i] == ' ' )
                    szPrefix[i] = '_';
            }

            pszRecord = (char *) CPLMalloc(nDSRSize+1);

            if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDSIndex, nRecord,
                                               pszRecord ) == FAILURE )
            {
                CPLFree( pszRecord );
                return;
            }

            pRecordDescr = EnvisatFile_GetRecordDescriptor(pszProduct, pszDSName);
            if (pRecordDescr)
            {
                pField = pRecordDescr->pFields;
                while ( pField && pField->szName )
                {
                    ret = EnvisatFile_GetFieldAsString(pszRecord, nDSRSize,
                                           pField, szValue);
                    if ( ret == CE_None )
                    {
                        if (nNumDsr == 1)
                            sprintf(szKey, "%s_%s", szPrefix, pField->szName);
                        else
                            // sprintf(szKey, "%s_%02d_%s", szPrefix, nRecord,
                            sprintf(szKey, "%s_%d_%s", szPrefix, nRecord,
                                    pField->szName);
                        SetMetadataItem(szKey, szValue, "RECORDS");
                    }
                    // silently ignore conversion errors

                    ++pField;
                }
            }
            CPLFree( pszRecord );
        }
    }
}
int EnvisatFile_Open( EnvisatFile **self_ptr, 
                      const char *filename, 
                      const char *mode )

{
    FILE	*fp;
    EnvisatFile	*self;
    char	mph_data[1248];
    char	*sph_data, *ds_data;
    int		sph_size, num_dsd, dsd_size, i;

    *self_ptr = NULL;

    /*
     * Check for legal mode argument.  Force to be binary for correct
     * operation on DOS file systems.
     */
    if( strcmp(mode,"r") == 0 )
        mode = "rb";
    else if( strcmp(mode,"r+") == 0 )
        mode = "rb+";
    else
    {
        SendError( "Illegal mode value used in EnvisatFile_Open(), only "
                   "\"r\" and \"r+\" are supported." );
        return FAILURE;
    }

    /*
     * Try to open the file, and report failure. 
     */

    fp = fopen( filename, mode );

    if( fp == NULL )
    {
        char	error_buf[2048];

        sprintf( error_buf, 
                 "Unable to open file \"%s\" in EnvisatFile_Open().", 
                 filename );

        SendError( error_buf );
        return FAILURE;
    }

    /*
     * Create, and initialize the EnvisatFile structure. 
     */
    self = (EnvisatFile *) calloc(sizeof(EnvisatFile),1);
    if( self == NULL )
        return FAILURE;

    self->fp = fp;
    self->filename = strdup( filename );
    self->header_dirty = 0;
    self->updatable = (strcmp(mode,"rb+") == 0);

    /*
     * Read the MPH, and process it as a group of name/value pairs. 
     */

    if( fread( mph_data, 1, MPH_SIZE, fp ) != MPH_SIZE )
    {
        free( self );
        SendError( "fread() for mph failed." );
        return FAILURE;
    }

    mph_data[MPH_SIZE] = '\0';
    if( S_NameValueList_Parse( mph_data, 0, 
                               &(self->mph_count), 
                               &(self->mph_entries) ) == FAILURE )
        return FAILURE;

    /*
     * Is this an incomplete level 0 file?
     */
    if( EnvisatFile_GetKeyValueAsInt( self, MPH, "SPH_SIZE", -1 ) == 0 
        && strncmp(EnvisatFile_GetKeyValueAsString( self, MPH, "PRODUCT", ""),
                   "ASA_IM__0P", 10) == 0 )
    {

        if( EnvisatFile_SetupLevel0( self ) == FAILURE )
        {
            EnvisatFile_Close( self );
            return FAILURE;
        }
        else
        {
            *self_ptr = self;
            return SUCCESS;
        }
    }

    /*
     * Read the SPH, and process it as a group of name/value pairs.  
     */
    sph_size = EnvisatFile_GetKeyValueAsInt( self, MPH, "SPH_SIZE", 0 );

    if( sph_size == 0 )							
    {
        SendError( "File does not appear to have SPH,"
                   " SPH_SIZE not set, or zero." );
        return FAILURE;
    }

    sph_data = (char *) malloc(sph_size + 1 );
    if( sph_data == NULL )
        return FAILURE;

    if( (int) fread( sph_data, 1, sph_size, fp ) != sph_size )
    {
        free( self );
        SendError( "fread() for sph failed." );
        return FAILURE;
    }

    sph_data[sph_size] = '\0';
    ds_data = strstr(sph_data,"DS_NAME");
    if( ds_data != NULL )
    {
        self->dsd_offset = (int) (ds_data - sph_data) + MPH_SIZE;
        *(ds_data-1) = '\0';
    }

    if( S_NameValueList_Parse( sph_data, MPH_SIZE,
                               &(self->sph_count), 
                               &(self->sph_entries) ) == FAILURE )
        return FAILURE;

    /*
     * Parse the Dataset Definitions.
     */
    num_dsd = EnvisatFile_GetKeyValueAsInt( self, MPH, "NUM_DSD", 0 );
    dsd_size = EnvisatFile_GetKeyValueAsInt( self, MPH, "DSD_SIZE", 0 );
    
    if( num_dsd > 0 && ds_data == NULL )
    {
        SendError( "DSDs indicated in MPH, but not found in SPH." );
        return FAILURE;
    }

    self->ds_info = (EnvisatDatasetInfo **) 
        calloc(sizeof(EnvisatDatasetInfo*),num_dsd);
    if( self->ds_info == NULL )
        return FAILURE;

    for( i = 0; i < num_dsd; i++ )
    {
        int	dsdh_count = 0;
        EnvisatNameValue **dsdh_entries = NULL;
        char	*dsd_data;
        EnvisatDatasetInfo *ds_info;

        /*
         * We parse each DSD grouping into a name/value list. 
         */
        dsd_data = ds_data + i * dsd_size;
        dsd_data[dsd_size-1] = '\0';
        
        if( S_NameValueList_Parse( dsd_data, 0, 
                                   &dsdh_count, &dsdh_entries ) == FAILURE )
            return FAILURE;

        /* 
         * Then build the dataset into structure from that. 
         */
        ds_info = (EnvisatDatasetInfo *) calloc(sizeof(EnvisatDatasetInfo),1);

        ds_info->ds_name = strdup( 
            S_NameValueList_FindValue( "DS_NAME", 
                                       dsdh_count, dsdh_entries, "" ));
        ds_info->ds_type = strdup( 
            S_NameValueList_FindValue( "DS_TYPE", 
                                       dsdh_count, dsdh_entries, "" ));
        ds_info->filename = strdup( 
            S_NameValueList_FindValue( "FILENAME", 
                                       dsdh_count, dsdh_entries, "" ));
        ds_info->ds_offset = atoi(
            S_NameValueList_FindValue( "DS_OFFSET", 
                                       dsdh_count, dsdh_entries, "0" ));
        ds_info->ds_size = atoi(
            S_NameValueList_FindValue( "DS_SIZE", 
                                       dsdh_count, dsdh_entries, "0" ));
        ds_info->num_dsr = atoi(
            S_NameValueList_FindValue( "NUM_DSR", 
                                       dsdh_count, dsdh_entries, "0" ));
        ds_info->dsr_size = atoi(
            S_NameValueList_FindValue( "DSR_SIZE", 
                                       dsdh_count, dsdh_entries, "0" ));

        S_NameValueList_Destroy( &dsdh_count, &dsdh_entries );

        self->ds_info[i] = ds_info;
        self->ds_count++;
    }
    
    free( sph_data );

    /*
     * Return successfully.
     */
    *self_ptr = self;

    return SUCCESS;
}