Esempio n. 1
0
GDALDataset *ELASDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*	First we check to see if the file has the expected header	*/
/*	bytes.								*/    
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 256 )
        return NULL;

    if( CPL_MSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+0))) != 1024
        || CPL_MSBWORD32(*((GInt32 *) (poOpenInfo->pabyHeader+28))) != 4321 )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ELASDataset 	*poDS;
    const char	 	*pszAccess;

    if( poOpenInfo->eAccess == GA_Update )
        pszAccess = "r+b";
    else
        pszAccess = "rb";

    poDS = new ELASDataset();

    poDS->fp = VSIFOpen( poOpenInfo->pszFilename, pszAccess );
    if( poDS->fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to open `%s' with acces `%s' failed.\n",
                  poOpenInfo->pszFilename, pszAccess );
        delete poDS;
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Read the header information.                                    */
/* -------------------------------------------------------------------- */
    poDS->bHeaderModified = FALSE;
    if( VSIFRead( &(poDS->sHeader), 1024, 1, poDS->fp ) != 1 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Attempt to read 1024 byte header filed on file %s\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Extract information of interest from the header.                */
/* -------------------------------------------------------------------- */
    int		nStart, nEnd, nELASDataType, nBytesPerSample;
    
    poDS->nLineOffset = CPL_MSBWORD32( poDS->sHeader.NBPR );

    nStart = CPL_MSBWORD32( poDS->sHeader.IL );
    nEnd = CPL_MSBWORD32( poDS->sHeader.LL );
    poDS->nRasterYSize = nEnd - nStart + 1;

    nStart = CPL_MSBWORD32( poDS->sHeader.IE );
    nEnd = CPL_MSBWORD32( poDS->sHeader.LE );
    poDS->nRasterXSize = nEnd - nStart + 1;

    poDS->nBands = CPL_MSBWORD32( poDS->sHeader.NC );

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(poDS->nBands, FALSE))
    {
        delete poDS;
        return NULL;
    }

    nELASDataType = (poDS->sHeader.IH19[2] & 0x7e) >> 2;
    nBytesPerSample = poDS->sHeader.IH19[3];
    
    if( nELASDataType == 0 && nBytesPerSample == 1 )
        poDS->eRasterDataType = GDT_Byte;
    else if( nELASDataType == 1 && nBytesPerSample == 1 )
        poDS->eRasterDataType = GDT_Byte;
    else if( nELASDataType == 16 && nBytesPerSample == 4 )
        poDS->eRasterDataType = GDT_Float32;
    else if( nELASDataType == 17 && nBytesPerSample == 8 )
        poDS->eRasterDataType = GDT_Float64;
    else
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unrecognised image data type %d, with BytesPerSample=%d.\n",
                  nELASDataType, nBytesPerSample );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*	Band offsets are always multiples of 256 within a multi-band	*/
/*	scanline of data.						*/
/* -------------------------------------------------------------------- */
    poDS->nBandOffset =
        (poDS->nRasterXSize * GDALGetDataTypeSize(poDS->eRasterDataType)/8);

    if( poDS->nBandOffset % 256 != 0 )
    {
        poDS->nBandOffset =
            poDS->nBandOffset - (poDS->nBandOffset % 256) + 256;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int		iBand;

    for( iBand = 0; iBand < poDS->nBands; iBand++ )
    {
        poDS->SetBand( iBand+1, new ELASRasterBand( poDS, iBand+1 ) );
    }

/* -------------------------------------------------------------------- */
/*	Extract the projection coordinates, if present.			*/
/* -------------------------------------------------------------------- */
    if( poDS->sHeader.XOffset != 0 )
    {
        CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
        CPL_MSBPTR32(&(poDS->sHeader.YPixSize));

        poDS->adfGeoTransform[0] =
            (GInt32) CPL_MSBWORD32(poDS->sHeader.XOffset);
        poDS->adfGeoTransform[1] = poDS->sHeader.XPixSize;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] =
            (GInt32) CPL_MSBWORD32(poDS->sHeader.YOffset);
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = -1.0 * ABS(poDS->sHeader.YPixSize);

        CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
        CPL_MSBPTR32(&(poDS->sHeader.YPixSize));

        poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
        poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;
    }
    else
    {
        poDS->adfGeoTransform[0] = 0.0;
        poDS->adfGeoTransform[1] = 1.0;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = 0.0;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = 1.0;
    }
    
/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

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

    return( poDS );
}
Esempio n. 2
0
GDALDataset *ELASDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( !Identify(poOpenInfo) || poOpenInfo->fpL == nullptr)
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */

    ELASDataset *poDS = new ELASDataset();
    poDS->eAccess = poOpenInfo->eAccess;
    poDS->fp = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

/* -------------------------------------------------------------------- */
/*      Read the header information.                                    */
/* -------------------------------------------------------------------- */
    poDS->bHeaderModified = FALSE;
    if( VSIFReadL( &(poDS->sHeader), 1024, 1, poDS->fp ) != 1 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Attempt to read 1024 byte header filed on file %s\n",
                  poOpenInfo->pszFilename );
        delete poDS;
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Extract information of interest from the header.                */
/* -------------------------------------------------------------------- */
    poDS->nLineOffset = CPL_MSBWORD32( poDS->sHeader.NBPR );

    int nStart = CPL_MSBWORD32( poDS->sHeader.IL );
    int nEnd = CPL_MSBWORD32( poDS->sHeader.LL );
    GIntBig nDiff = static_cast<GIntBig>(nEnd) - nStart + 1;

    if( nDiff <= 0 || nDiff > std::numeric_limits<int>::max() )
    {
        delete poDS;
        return nullptr;
    }
    poDS->nRasterYSize = static_cast<int>(nDiff);

    nStart = CPL_MSBWORD32( poDS->sHeader.IE );
    nEnd = CPL_MSBWORD32( poDS->sHeader.LE );
    nDiff = static_cast<GIntBig>(nEnd) - nStart + 1;
    if( nDiff <= 0 || nDiff > std::numeric_limits<int>::max() )
    {
        delete poDS;
        return nullptr;
    }
    poDS->nRasterXSize = static_cast<int>(nDiff);

    poDS->nBands = CPL_MSBWORD32( poDS->sHeader.NC );

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(poDS->nBands, FALSE))
    {
        delete poDS;
        return nullptr;
    }

    const int nELASDataType = (poDS->sHeader.IH19[2] & 0x7e) >> 2;
    const int nBytesPerSample = poDS->sHeader.IH19[3];

    if( nELASDataType == 0 && nBytesPerSample == 1 )
        poDS->eRasterDataType = GDT_Byte;
    else if( nELASDataType == 1 && nBytesPerSample == 1 )
        poDS->eRasterDataType = GDT_Byte;
    else if( nELASDataType == 16 && nBytesPerSample == 4 )
        poDS->eRasterDataType = GDT_Float32;
    else if( nELASDataType == 17 && nBytesPerSample == 8 )
        poDS->eRasterDataType = GDT_Float64;
    else
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unrecognized image data type %d, with BytesPerSample=%d.\n",
                  nELASDataType, nBytesPerSample );
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Band offsets are always multiples of 256 within a multi-band    */
/*      scanline of data.                                               */
/* -------------------------------------------------------------------- */
    if( GDALGetDataTypeSizeBytes(poDS->eRasterDataType) >
        (std::numeric_limits<int>::max() - 256) / poDS->nRasterXSize )
    {
        delete poDS;
        return nullptr;
    }
    poDS->nBandOffset =
        (poDS->nRasterXSize * GDALGetDataTypeSizeBytes(poDS->eRasterDataType));

    if( poDS->nBandOffset > 1000000 )
    {
        VSIFSeekL( poDS->fp, 0, SEEK_END );
        if( VSIFTellL( poDS->fp ) < static_cast<vsi_l_offset>(poDS->nBandOffset) )
        {
            CPLError(CE_Failure, CPLE_FileIO, "File too short");
            delete poDS;
            return nullptr;
        }
    }

    if( poDS->nBandOffset % 256 != 0 )
    {
        poDS->nBandOffset =
            poDS->nBandOffset - (poDS->nBandOffset % 256) + 256;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    /* coverity[tainted_data] */
    for( int iBand = 0; iBand < poDS->nBands; iBand++ )
    {
        poDS->SetBand( iBand+1, new ELASRasterBand( poDS, iBand+1 ) );
    }

/* -------------------------------------------------------------------- */
/*      Extract the projection coordinates, if present.                 */
/* -------------------------------------------------------------------- */
    if( poDS->sHeader.XOffset != 0 )
    {
        CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
        CPL_MSBPTR32(&(poDS->sHeader.YPixSize));

        poDS->adfGeoTransform[0] =
            (GInt32) CPL_MSBWORD32(poDS->sHeader.XOffset);
        poDS->adfGeoTransform[1] = poDS->sHeader.XPixSize;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] =
            (GInt32) CPL_MSBWORD32(poDS->sHeader.YOffset);
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = -1.0 * std::abs(poDS->sHeader.YPixSize);

        CPL_MSBPTR32(&(poDS->sHeader.XPixSize));
        CPL_MSBPTR32(&(poDS->sHeader.YPixSize));

        poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
        poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;
    }
    else
    {
        poDS->adfGeoTransform[0] = 0.0;
        poDS->adfGeoTransform[1] = 1.0;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = 0.0;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = 1.0;
    }

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

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

    return poDS;
}