int EnvisatFile_Create( EnvisatFile **self_ptr, 
                        const char *filename, 
                        const char *template_file )

{
    int		template_size;
    char	*template_data;
    FILE	*fp;

    /*
     * Try to open the template file, and read it into memory.
     */

    fp = fopen( template_file, "rb" );

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

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

        SendError( error_buf );
        return FAILURE;
    }

    fseek( fp, 0, SEEK_END );
    template_size = (int) ftell( fp );

    template_data = (char *) malloc(template_size);
    
    fseek( fp, 0, SEEK_SET );
    fread( template_data, template_size, 1, fp );
    fclose( fp );

    /*
     * Try to write the template out to the new filename. 
     */
    
    fp = fopen( filename, "wb" );
    if( fp == NULL )
    {
        char	error_buf[2048];

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

        SendError( error_buf );
        return FAILURE;
    }

    fwrite( template_data, template_size, 1, fp );
    fclose( fp );

    free( template_data );

    /*
     * Now just open the file normally. 
     */
    
    return EnvisatFile_Open( self_ptr, filename, "r+" );
}
Exemple #2
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 );
}
Exemple #3
0
int main( int argc, char ** argv )

{
    EnvisatFile	*es_file;
    int	        ds_index;
    int	ds_offset, ds_size, num_dsr, dsr_size, i_record;

    if( argc != 2 )
    {
        printf( "Usage: dumpgeo filename\n" );
        exit( 1 );
    }

    if( EnvisatFile_Open( &es_file, argv[1], "r" ) != 0 )
    {
        printf( "EnvisatFile_Open(%s) failed.\n", argv[1] );
        exit( 2 );
    }

    ds_index = EnvisatFile_GetDatasetIndex( es_file, "GEOLOCATION GRID ADS" );
    if( ds_index == -1 )
    {
        printf( "Can't find geolocation grid ads.\n" );
        exit( 3 );
    }

    EnvisatFile_GetDatasetInfo( es_file,
                                ds_index, NULL, NULL, NULL,
                                &ds_offset, &ds_size,
                                &num_dsr, &dsr_size );
    if( ds_offset == 0 )
    {
        printf( "No data for geolocation grid ads.\n" );
        exit( 4 );
    }

    CPLAssert( dsr_size == 521 );

    for( i_record = 0; i_record < num_dsr; i_record++ )
    {
        GByte	abyRecord[521];
        GUInt32	unValue;
        float   fValue;
        int	sample;

        EnvisatFile_ReadDatasetRecord( es_file, ds_index, i_record,
                                       abyRecord );

        printf( "<====================== Record %d ==================>\n",
                i_record );

        /* field 1 */
        CPL_SWAP32PTR( abyRecord + 0 );
        CPL_SWAP32PTR( abyRecord + 4 );
        CPL_SWAP32PTR( abyRecord + 8 );

        printf( "start line: mjd_days = %d, sec = %d, msec = %d\n",
                ((int *) abyRecord)[0],
                ((unsigned int *) abyRecord)[1],
                ((unsigned int *) abyRecord)[2] );

        /* field 2 */
        printf( "Attachment flag = %d\n", abyRecord[12] );

        /* field 3 */
        memcpy( &unValue, abyRecord + 13, 4 );
        printf( "range line (first in granule) = %d\n",
                CPL_SWAP32( unValue ) );

        /* field 4 */
        memcpy( &unValue, abyRecord + 17, 4 );
        printf( "lines in granule = %d\n", CPL_SWAP32( unValue ) );

        /* field 5 */
        memcpy( &fValue, abyRecord + 21, 4 );
        CPL_SWAP32PTR( &fValue );
        printf( "track heading (first line) = %f\n", fValue );

        /* field 6 */

        printf( "first line of granule:\n" );
        for( sample = 0; sample < 11; sample++ )
        {
            memcpy( &unValue, abyRecord + 25 + sample*4, 4 );
            printf( "  sample=%d ", CPL_SWAP32(unValue) );

            memcpy( &fValue, abyRecord + 25 + 44 + sample * 4, 4 );
            CPL_SWAP32PTR( &fValue );
            printf( "time=%g ", fValue );

            memcpy( &fValue, abyRecord + 25 + 88 + sample * 4, 4 );
            CPL_SWAP32PTR( &fValue );
            printf( "angle=%g ", fValue );

            memcpy( &unValue, abyRecord + 25 + 132 + sample*4, 4 );
            printf( "(%.9f,", ((int) CPL_SWAP32(unValue)) * 0.000001 );

            memcpy( &unValue, abyRecord + 25 + 176 + sample*4, 4 );
            printf( "%.9f)\n", ((int) CPL_SWAP32(unValue)) * 0.000001 );
        }

        /* field 8 */
        CPL_SWAP32PTR( abyRecord + 267 );
        CPL_SWAP32PTR( abyRecord + 271 );
        CPL_SWAP32PTR( abyRecord + 275 );

        printf( "end line: mjd_days = %d, sec = %d, msec = %d\n",
                ((int *) (abyRecord + 267))[0],
                ((unsigned int *) (abyRecord + 267))[1],
                ((unsigned int *) (abyRecord + 267))[2] );

        /* field 9 */
        printf( "final line of granule:\n" );
        for( sample = 0; sample < 11; sample++ )
        {
            memcpy( &unValue, abyRecord + 279 + sample*4, 4 );
            printf( "  sample=%d ", CPL_SWAP32(unValue) );

            memcpy( &fValue, abyRecord + 279 + 44 + sample * 4, 4 );
            CPL_SWAP32PTR( &fValue );
            printf( "time=%g ", fValue );

            memcpy( &fValue, abyRecord + 279 + 88 + sample * 4, 4 );
            CPL_SWAP32PTR( &fValue );
            printf( "angle=%g ", fValue );

            memcpy( &unValue, abyRecord + 279 + 132 + sample*4, 4 );
            printf( "(%.9f,", ((int) CPL_SWAP32(unValue)) * 0.000001 );

            memcpy( &unValue, abyRecord + 279 + 176 + sample*4, 4 );
            printf( "%.9f)\n", ((int) CPL_SWAP32(unValue)) * 0.000001 );
        }
    }

    EnvisatFile_Close( es_file );

    exit( 0 );
}