Esempio n. 1
0
int OGRGPXDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GPX driver does not support opening a file in update mode");
        return FALSE;
    }
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Determine what sort of object this is.                          */
/* -------------------------------------------------------------------- */
    VSIStatBufL sStatBuf;

    if( VSIStatL( pszFilename, &sStatBuf ) != 0 )
        return FALSE;
    
    if( VSI_ISDIR(sStatBuf.st_mode) )
        return FALSE;

    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    validity = GPX_VALIDITY_UNKNOWN;
    CPLFree(pszVersion);
    pszVersion = NULL;
    bUseExtensions = FALSE;
    nElementsRead = 0;
    
    XML_Parser oParser = OGRCreateExpatXMLParser();
    oCurrentParser = oParser;
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <gpx> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx"))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of GPX file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            validity = GPX_VALIDITY_INVALID;
            break;
        }
        if (validity == GPX_VALIDITY_INVALID)
        {
            break;
        }
        else if (validity == GPX_VALIDITY_VALID)
        {
            /* If we have recognized the <gpx> element, now we try */
            /* to recognize if they are <extensions> tags */
            /* But we stop to look for after an arbitrary number of tags */
            if (bUseExtensions)
                break;
            else if (nElementsRead > 200)
                break;
        }
        else
        {
            /* After reading 50 * BUFSIZE bytes, and not finding whether the file */
            /* is GPX or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );
    
    XML_ParserFree(oParser);
    
    VSIFCloseL(fp);
    
    if (validity == GPX_VALIDITY_VALID)
    {
        CPLDebug("GPX", "%s seems to be a GPX file.", pszFilename);
        if (bUseExtensions)
            CPLDebug("GPX", "It uses <extensions>");

        if (pszVersion == NULL)
        {
            /* Default to 1.1 */
            CPLError(CE_Warning, CPLE_AppDefined, "GPX schema version is unknown. "
                     "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1.");
            pszVersion = CPLStrdup("1.1");
        }
        else if (strcmp(pszVersion, "1.0") == 0 || strcmp(pszVersion, "1.1") == 0)
        {
            /* Fine */
        }
        else
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "GPX schema version '%s' is not handled by the driver. "
                     "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1.", pszVersion);
        }

        nLayers = 5;
        papoLayers = (OGRGPXLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGPXLayer*));
        papoLayers[0] = new OGRGPXLayer( pszName, "waypoints", GPX_WPT, this, FALSE );
        papoLayers[1] = new OGRGPXLayer( pszName, "routes", GPX_ROUTE, this, FALSE );
        papoLayers[2] = new OGRGPXLayer( pszName, "tracks", GPX_TRACK, this, FALSE );
        papoLayers[3] = new OGRGPXLayer( pszName, "route_points", GPX_ROUTE_POINT, this, FALSE );
        papoLayers[4] = new OGRGPXLayer( pszName, "track_points", GPX_TRACK_POINT, this, FALSE );
    }

    return (validity == GPX_VALIDITY_VALID);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx"))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GPX driver has not been built with read support. Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}
Esempio n. 2
0
void E00GRIDDataset::ReadMetadata()

{
    if (bHasReadMetadata)
        return;

    bHasReadMetadata = TRUE;

    if (e00ReadPtr == NULL)
    {
        int nRoundedBlockXSize = ((nRasterXSize + VALS_PER_LINE - 1) /
                                                VALS_PER_LINE) * VALS_PER_LINE;
        vsi_l_offset nValsToSkip =
                               (vsi_l_offset)nRasterYSize * nRoundedBlockXSize;
        vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE;
        int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + nBytesEOL;
        vsi_l_offset nPos = nDataStart + nLinesToSkip * nBytesPerLine;
        VSIFSeekL(fp, nPos, SEEK_SET);
    }
    else
    {
        nLastYOff = -1;

        const unsigned int BUFFER_SIZE = 65536;
        const unsigned int NEEDLE_SIZE = 3*5;
        const unsigned int nToRead = BUFFER_SIZE - NEEDLE_SIZE;
        char* pabyBuffer = (char*)CPLCalloc(1, BUFFER_SIZE+NEEDLE_SIZE);
        int nRead;
        int bEOGFound = FALSE;

        VSIFSeekL(fp, 0, SEEK_END);
        vsi_l_offset nEndPos = VSIFTellL(fp);
        if (nEndPos > BUFFER_SIZE)
            nEndPos -= BUFFER_SIZE;
        else
            nEndPos = 0;
        VSIFSeekL(fp, nEndPos, SEEK_SET);

#define GOTO_NEXT_CHAR() \
    i ++; \
    if (pabyBuffer[i] == 13 || pabyBuffer[i] == 10) \
    { \
        i++; \
        if (pabyBuffer[i] == 10) \
            i++; \
    } \

        while ((nRead = VSIFReadL(pabyBuffer, 1, nToRead, fp)) != 0)
        {
            int i;
            for(i = 0; i < nRead; i++)
            {
                if (pabyBuffer[i] == 'E')
                {
                    GOTO_NEXT_CHAR();
                    if (pabyBuffer[i] == 'O')
                    {
                        GOTO_NEXT_CHAR();
                        if (pabyBuffer[i] == 'G')
                        {
                            GOTO_NEXT_CHAR();
                            if (pabyBuffer[i] == '~')
                            {
                                GOTO_NEXT_CHAR();
                                if (pabyBuffer[i] == '}')
                                {
                                    bEOGFound = TRUE;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (bEOGFound)
            {
                VSIFSeekL(fp, VSIFTellL(fp) - nRead + i + 1, SEEK_SET);
                e00ReadPtr->iInBufPtr = 0;
                e00ReadPtr->szInBuf[0] = '\0';
                break;
            }

            if (nEndPos == 0)
                break;

            if ((unsigned int)nRead == nToRead)
            {
                memmove(pabyBuffer + nToRead, pabyBuffer, NEEDLE_SIZE);
                if (nEndPos >= (vsi_l_offset)nToRead)
                    nEndPos -= nToRead;
                else
                    nEndPos = 0;
                VSIFSeekL(fp, nEndPos, SEEK_SET);
            }
            else
                break;
        }
        CPLFree(pabyBuffer);
        if (!bEOGFound)
            return;
    }

    const char* pszLine;
    int bPRJFound = FALSE;
    int bStatsFound = FALSE;
    while((pszLine = ReadLine()) != NULL)
    {
        if (EQUALN(pszLine, "PRJ  2", 6))
        {
            bPRJFound = TRUE;
            while((pszLine = ReadLine()) != NULL)
            {
                if (EQUAL(pszLine, "EOP"))
                {
                    break;
                }
                papszPrj = CSLAddString(papszPrj, pszLine);
            }

            OGRSpatialReference oSRS;
            if( oSRS.importFromESRI( papszPrj ) != OGRERR_NONE )
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                            "Failed to parse PRJ section, ignoring." );
            }
            else
            {
                char* pszWKT = NULL;
                if (oSRS.exportToWkt(&pszWKT) == OGRERR_NONE && pszWKT != NULL)
                    osProjection = pszWKT;
                CPLFree(pszWKT);
            }
            if (bStatsFound)
                break;
        }
        else if (strcmp(pszLine, "STDV              8-1  254-1  15 3 60-1  -1  -1-1                   4-") == 0)
        {
            bStatsFound = TRUE;
            pszLine = ReadLine();
            if (pszLine)
            {
                CPLString osStats = pszLine;
                pszLine = ReadLine();
                if (pszLine)
                {
                    osStats += pszLine;
                    char** papszTokens = CSLTokenizeString(osStats);
                    if (CSLCount(papszTokens) == 4)
                    {
                        dfMin = atof(papszTokens[0]);
                        dfMax = atof(papszTokens[1]);
                        dfMean = atof(papszTokens[2]);
                        dfStddev = atof(papszTokens[3]);
                        bHasStats = TRUE;
                    }
                    CSLDestroy(papszTokens);
                }
            }
            if (bPRJFound)
                break;
        }
    }
}
Esempio n. 3
0
CPLErr OZIRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )

{
    OZIDataset *poGDS = (OZIDataset *) poDS;

    int nBlock = nBlockYOff * nXBlocks + nBlockXOff;

    VSIFSeekL(poGDS->fp, poGDS->panZoomLevelOffsets[nZoomLevel] +
                         12 + 1024 + 4 * nBlock, SEEK_SET);
    int nPointer = ReadInt(poGDS->fp, poGDS->bOzi3, poGDS->nKeyInit);
    if (nPointer < 0  || (vsi_l_offset)nPointer >= poGDS->nFileSize)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Invalid offset for block (%d, %d) : %d",
                 nBlockXOff, nBlockYOff, nPointer);
        return CE_Failure;
    }
    int nNextPointer = ReadInt(poGDS->fp, poGDS->bOzi3, poGDS->nKeyInit);
    if (nNextPointer <= nPointer + 16  ||
        (vsi_l_offset)nNextPointer >= poGDS->nFileSize)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Invalid next offset for block (%d, %d) : %d",
                 nBlockXOff, nBlockYOff, nNextPointer);
        return CE_Failure;
    }

    VSIFSeekL(poGDS->fp, nPointer, SEEK_SET);

    int nToRead = nNextPointer - nPointer;
    GByte* pabyZlibBuffer = (GByte*)CPLMalloc(nToRead);
    if (VSIFReadL(pabyZlibBuffer, nToRead, 1, poGDS->fp) != 1)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Not enough byte read for block (%d, %d)",
                 nBlockXOff, nBlockYOff);
        CPLFree(pabyZlibBuffer);
        return CE_Failure;
    }

    if (poGDS->bOzi3)
        OZIDecrypt(pabyZlibBuffer, 16, poGDS->nKeyInit);

    if (pabyZlibBuffer[0] != 0x78 ||
        pabyZlibBuffer[1] != 0xDA)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Bad ZLIB signature for block (%d, %d) : 0x%02X 0x%02X",
                 nBlockXOff, nBlockYOff, pabyZlibBuffer[0], pabyZlibBuffer[1]);
        CPLFree(pabyZlibBuffer);
        return CE_Failure;
    }

    z_stream      stream;
    stream.zalloc = (alloc_func)0;
    stream.zfree = (free_func)0;
    stream.opaque = (voidpf)0;
    stream.next_in = pabyZlibBuffer + 2;
    stream.avail_in = nToRead - 2;

    int err = inflateInit2(&(stream), -MAX_WBITS);

    int i;
    for(i=0;i<64 && err == Z_OK;i++)
    {
        stream.next_out = (Bytef*)pImage + (63 - i) * 64;
        stream.avail_out = 64;
        err = inflate(& (stream), Z_NO_FLUSH);
        if (err != Z_OK && err != Z_STREAM_END)
            break;

        if (pabyTranslationTable)
        {
            int j;
            GByte* ptr = ((GByte*)pImage) + (63 - i) * 64;
            for(j=0;j<64;j++)
            {
                *ptr = pabyTranslationTable[*ptr];
                ptr ++;
            }
        }
    }

    inflateEnd(&stream);

    CPLFree(pabyZlibBuffer);

    return (err == Z_OK || err == Z_STREAM_END) ? CE_None : CE_Failure;
}
Esempio n. 4
0
int OGRIdrisiDataSource::Open( const char * pszFilename )

{
    pszName = CPLStrdup( pszFilename );

    VSILFILE* fpVCT = VSIFOpenL(pszFilename, "rb");
    if (fpVCT == NULL)
        return FALSE;

    char* pszWTKString = NULL;

// --------------------------------------------------------------------
//      Look for .vdc file
// --------------------------------------------------------------------
    const char* pszVDCFilename = CPLResetExtension(pszFilename, "vdc");
    VSILFILE* fpVDC = VSIFOpenL(pszVDCFilename, "rb");
    if (fpVDC == NULL)
    {
        pszVDCFilename = CPLResetExtension(pszFilename, "VDC");
        fpVDC = VSIFOpenL(pszVDCFilename, "rb");
    }

    char** papszVDC = NULL;
    if (fpVDC != NULL)
    {
        VSIFCloseL(fpVDC);
        fpVDC = NULL;

        CPLPushErrorHandler(CPLQuietErrorHandler);
        papszVDC = CSLLoad2(pszVDCFilename, 1024, 256, NULL);
        CPLPopErrorHandler();
        CPLErrorReset();
    }

    OGRwkbGeometryType eType = wkbUnknown;

    if (papszVDC != NULL)
    {
        CSLSetNameValueSeparator( papszVDC, ":" );

        const char *pszVersion = CSLFetchNameValue( papszVDC, "file format " );

        if( pszVersion == NULL || !EQUAL( pszVersion, "IDRISI Vector A.1" ) )
        {
            CSLDestroy( papszVDC );
            VSIFCloseL(fpVCT);
            return FALSE;
        }

        const char *pszRefSystem
            = CSLFetchNameValue( papszVDC, "ref. system " );
        const char *pszRefUnits = CSLFetchNameValue( papszVDC, "ref. units  " );

        if (pszRefSystem != NULL && pszRefUnits != NULL)
            IdrisiGeoReference2Wkt( pszFilename, pszRefSystem, pszRefUnits,
                                    &pszWTKString);
    }

    GByte chType;
    if (VSIFReadL(&chType, 1, 1, fpVCT) != 1)
    {
        VSIFCloseL(fpVCT);
        CSLDestroy( papszVDC );
        return FALSE;
    }

    if (chType == 1)
        eType = wkbPoint;
    else if (chType == 2)
        eType = wkbLineString;
    else if (chType == 3)
        eType = wkbPolygon;
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Unsupport geometry type : %d",
                  static_cast<int>(chType) );
        VSIFCloseL(fpVCT);
        CSLDestroy( papszVDC );
        return FALSE;
    }

    const char *pszMinX = CSLFetchNameValue( papszVDC, "min. X      " );
    const char *pszMaxX = CSLFetchNameValue( papszVDC, "max. X      " );
    const char *pszMinY = CSLFetchNameValue( papszVDC, "min. Y      " );
    const char *pszMaxY = CSLFetchNameValue( papszVDC, "max. Y      " );

    OGRIdrisiLayer* poLayer = new OGRIdrisiLayer(pszFilename,
                                                 CPLGetBasename(pszFilename),
                                                 fpVCT, eType, pszWTKString);
    papoLayers = static_cast<OGRLayer**>( CPLMalloc(sizeof(OGRLayer*)) );
    papoLayers[nLayers ++] = poLayer;

    if( pszMinX != NULL && pszMaxX != NULL && pszMinY != NULL &&
        pszMaxY != NULL)
    {
        poLayer->SetExtent(
            CPLAtof(pszMinX), CPLAtof(pszMinY), CPLAtof(pszMaxX),
            CPLAtof(pszMaxY) );
    }

    CPLFree(pszWTKString);

    CSLDestroy( papszVDC );

    return TRUE;
}
Esempio n. 5
0
OGRDataSource *OGRPGeoDriver::Open( const char * pszFilename,
                                    int bUpdate )

{
    OGRPGeoDataSource     *poDS;

    if( !EQUALN(pszFilename,"PGEO:",5) 
        && !EQUAL(CPLGetExtension(pszFilename),"mdb") )
        return NULL;

    if( !EQUALN(pszFilename,"PGEO:",5) &&
        EQUAL(CPLGetExtension(pszFilename),"mdb") )
    {
        VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
        if (!fp)
            return NULL;
        GByte* pabyHeader = (GByte*) CPLMalloc(100000);
        VSIFReadL(pabyHeader, 100000, 1, fp);
        VSIFCloseL(fp);

        /* Look for GDB_GeomColumns table */
        const GByte pabyNeedle[] = { 'G', 0, 'D', 0, 'B', 0, '_', 0, 'G', 0, 'e', 0, 'o', 0, 'm', 0, 'C', 0, 'o', 0, 'l', 0, 'u', 0, 'm', 0, 'n', 0, 's' };
        int bFound = FALSE;
        for(int i=0;i<100000 - (int)sizeof(pabyNeedle);i++)
        {
            if (memcmp(pabyHeader + i, pabyNeedle, sizeof(pabyNeedle)) == 0)
            {
                bFound = TRUE;
                break;
            }
        }
        CPLFree(pabyHeader);
        if (!bFound)
            return NULL;
    }

#ifndef WIN32
    // Try to register MDB Tools driver
    //
    // ODBCINST.INI NOTE:
    // This operation requires write access to odbcinst.ini file
    // located in directory pointed by ODBCINISYS variable.
    // Usually, it points to /etc, so non-root users can overwrite this
    // setting ODBCINISYS with location they have write access to, e.g.:
    // $ export ODBCINISYS=$HOME/etc
    // $ touch $ODBCINISYS/odbcinst.ini
    //
    // See: http://www.unixodbc.org/internals.html
    //
    if ( !InstallMdbDriver() )
    {
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "Unable to install MDB driver for ODBC, MDB access may not supported.\n" );
    }
    else
        CPLDebug( "PGeo", "MDB Tools driver installed successfully!");

#endif /* ndef WIN32 */

    // Open data source
    poDS = new OGRPGeoDataSource();

    if( !poDS->Open( pszFilename, bUpdate, TRUE ) )
    {
        delete poDS;
        return NULL;
    }
    else
        return poDS;
}
Esempio n. 6
0
CPLErr HF2RasterBand::IReadBlock( int nBlockXOff, int nLineYOff,
                                  void * pImage )

{
    HF2Dataset *poGDS = (HF2Dataset *) poDS;

    int nXBlocks = (nRasterXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nRasterYSize + nBlockXSize - 1) / nBlockXSize;
    
    if (!poGDS->LoadBlockMap())
        return CE_Failure;
    
    if (pafBlockData == NULL)
    {
        pafBlockData = (float*)VSIMalloc3(nXBlocks * sizeof(float), poGDS->nTileSize, poGDS->nTileSize);
        if (pafBlockData == NULL)
            return CE_Failure;
    }
    
    nLineYOff = nRasterYSize - 1 - nLineYOff;

    int nBlockYOff = nLineYOff / nBlockXSize;
    int nYOffInTile = nLineYOff % nBlockXSize;

    if (nBlockYOff != nLastBlockYOff)
    {
        nLastBlockYOff = nBlockYOff;

        memset(pafBlockData, 0, nXBlocks * sizeof(float) * nBlockXSize * nBlockXSize);

        /* 4 * nBlockXSize is the upper bound */
        void* pabyData = CPLMalloc( 4 * nBlockXSize );

        int nxoff;
        for(nxoff = 0; nxoff < nXBlocks; nxoff++)
        {
            VSIFSeekL(poGDS->fp, poGDS->panBlockOffset[(nYBlocks - 1 - nBlockYOff) * nXBlocks + nxoff], SEEK_SET);
            float fScale, fOff;
            VSIFReadL(&fScale, 4, 1, poGDS->fp);
            VSIFReadL(&fOff, 4, 1, poGDS->fp);
            CPL_LSBPTR32(&fScale);
            CPL_LSBPTR32(&fOff);
    
            int nTileWidth = MIN(nBlockXSize, nRasterXSize - nxoff * nBlockXSize);
            int nTileHeight = MIN(nBlockXSize, nRasterYSize - nBlockYOff * nBlockXSize);
            
            int j;
            for(j=0;j<nTileHeight;j++)
            {
                GByte nWordSize;
                VSIFReadL(&nWordSize, 1, 1, poGDS->fp);
                if (nWordSize != 1 && nWordSize != 2 && nWordSize != 4)
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Unexpected word size : %d", (int)nWordSize);
                    break;
                }

                GInt32 nVal;
                VSIFReadL(&nVal, 4, 1, poGDS->fp);
                CPL_LSBPTR32(&nVal);
                VSIFReadL(pabyData, nWordSize * (nTileWidth - 1), 1, poGDS->fp);
#if defined(CPL_MSB)
                if (nWordSize > 1)
                    GDALSwapWords(pabyData, nWordSize, nTileWidth - 1, nWordSize);
#endif

                pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + 0] = nVal * fScale + fOff;
                int i;
                for(i=1;i<nTileWidth;i++)
                {
                    if (nWordSize == 1)
                        nVal += ((char*)pabyData)[i-1];
                    else if (nWordSize == 2)
                        nVal += ((GInt16*)pabyData)[i-1];
                    else
                        nVal += ((GInt32*)pabyData)[i-1];
                    pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + i] = nVal * fScale + fOff;
                }
            }
        }

        CPLFree(pabyData);
    }

    int nTileWidth = MIN(nBlockXSize, nRasterXSize - nBlockXOff * nBlockXSize);
    memcpy(pImage, pafBlockData + nBlockXOff * nBlockXSize * nBlockXSize +
                                  nYOffInTile * nBlockXSize,
           nTileWidth * sizeof(float));

    return CE_None;
}
Esempio n. 7
0
static tsize_t
_tiffReadProc(thandle_t th, tdata_t buf, tsize_t size)
{
    GDALTiffHandle* psGTH = (GDALTiffHandle*) th;
    return VSIFReadL( buf, 1, size, psGTH->fpL );
}
Esempio n. 8
0
int OGRHTFDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        return FALSE;
    }

    pszName = CPLStrdup( pszFilename );

// -------------------------------------------------------------------- 
//      Does this appear to be a .htf file?
// --------------------------------------------------------------------

    VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
    if (fp == NULL)
        return FALSE;

    char szBuffer[11];
    int nbRead = (int)VSIFReadL(szBuffer, 1, sizeof(szBuffer) - 1, fp);
    szBuffer[nbRead] = '\0';

    int bIsHTF = strcmp(szBuffer, "HTF HEADER") == 0;
    if (!bIsHTF)
    {
        VSIFCloseL(fp);
        return FALSE;
    }

    VSIFSeekL(fp, 0, SEEK_SET);

    const char* pszLine;
    int bEndOfHTFHeader = FALSE;
    int bIsSouth = FALSE;
    int bGeodeticDatumIsWGS84 = FALSE;
    int bIsUTM = FALSE;
    int nZone = 0;
    int nLines = 0;
    int bHasSWEasting = FALSE, bHasSWNorthing = FALSE, bHasNEEasting = FALSE, bHasNENorthing = FALSE;
    double dfSWEasting = 0, dfSWNorthing = 0, dfNEEasting = 0, dfNENorthing = 0;
    std::vector<CPLString> aosMD;
    int nTotalSoundings = 0;
    while( (pszLine = CPLReadLine2L(fp, 1024, NULL)) != NULL)
    {
        nLines ++;
        if (nLines == 1000)
        {
            break;
        }
        if (*pszLine == ';' || *pszLine == '\0')
            continue;

        if (strcmp(pszLine, "END OF HTF HEADER") == 0)
        {
            bEndOfHTFHeader = TRUE;
            break;
        }

        aosMD.push_back(pszLine);

        if (strncmp(pszLine, "GEODETIC DATUM: ", 16) == 0)
        {
            if (strcmp(pszLine + 16, "WG84") == 0 ||
                strcmp(pszLine + 16, "WGS84") == 0)
                bGeodeticDatumIsWGS84 = TRUE;
            else
            {
                VSIFCloseL(fp);
                CPLError(CE_Failure, CPLE_NotSupported,
                         "Unsupported datum : %s", pszLine + 16);
                return FALSE;
            }
        }
        else if (strncmp(pszLine, "NE LATITUDE: -", 14) == 0)
            bIsSouth = TRUE;
        else if (strncmp(pszLine, "GRID REFERENCE SYSTEM: ", 23) == 0)
        {
            if (strncmp(pszLine + 23, "UTM", 3) == 0)
                bIsUTM = TRUE;
            else
            {
                VSIFCloseL(fp);
                CPLError(CE_Failure, CPLE_NotSupported,
                         "Unsupported grid : %s", pszLine + 23);
                return FALSE;
            }
        }
        else if (strncmp(pszLine, "GRID ZONE: ", 11) == 0)
        {
            nZone = atoi(pszLine + 11);
        }
        else if (strncmp(pszLine, "SW GRID COORDINATE - EASTING: ", 30) == 0)
        {
            bHasSWEasting = TRUE;
            dfSWEasting = atof(pszLine + 30);
        }
        else if (strncmp(pszLine, "SW GRID COORDINATE - NORTHING: ", 31) == 0)
        {
            bHasSWNorthing = TRUE;
            dfSWNorthing = atof(pszLine + 31);
        }
        else if (strncmp(pszLine, "NE GRID COORDINATE - EASTING: ", 30) == 0)
        {
            bHasNEEasting = TRUE;
            dfNEEasting = atof(pszLine + 30);
        }
        else if (strncmp(pszLine, "NE GRID COORDINATE - NORTHING: ", 31) == 0)
        {
            bHasNENorthing = TRUE;
            dfNENorthing = atof(pszLine + 31);
        }
        else if (strncmp(pszLine, "TOTAL SOUNDINGS: ", 17) == 0)
        {
            nTotalSoundings = atoi(pszLine + 17);
        }
    }

    VSIFCloseL(fp);

    if (!bEndOfHTFHeader)
        return FALSE;
    if (!bGeodeticDatumIsWGS84)
        return FALSE;
    if (!bIsUTM)
        return FALSE;
    if (nZone == 0)
        return FALSE;
  
    nLayers = 2;
    papoLayers = (OGRHTFLayer**) CPLMalloc(sizeof(OGRHTFLayer*) * 2);
    papoLayers[0] = new OGRHTFPolygonLayer(pszFilename, nZone, !bIsSouth);
    papoLayers[1] = new OGRHTFSoundingLayer(pszFilename, nZone, !bIsSouth, nTotalSoundings);

    if (bHasSWEasting && bHasSWNorthing && bHasNEEasting && bHasNENorthing)
    {
        papoLayers[0]->SetExtent(dfSWEasting, dfSWNorthing, dfNEEasting, dfNENorthing);
        papoLayers[1]->SetExtent(dfSWEasting, dfSWNorthing, dfNEEasting, dfNENorthing);
    }

    poMetadataLayer = new OGRHTFMetadataLayer(aosMD);

    return TRUE;
}
GDALDataset *XPMDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      First we check to see if the file has the expected header       */
/*      bytes.  For now we expect the XPM file to start with a line     */
/*      containing the letters XPM, and to have "static" in the         */
/*      header.                                                         */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 32 
        || strstr((const char *) poOpenInfo->pabyHeader,"XPM") == NULL 
        || strstr((const char *) poOpenInfo->pabyHeader,"static") == NULL )
        return NULL;

    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The XPM driver does not support update access to existing"
                  " files." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the whole file into a memory strings.                      */
/* -------------------------------------------------------------------- */
    unsigned int nFileSize;
    char *pszFileContents;
    VSILFILE *fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    if( fp == NULL )
        return NULL;

    VSIFSeekL( fp, 0, SEEK_END );
    nFileSize = VSIFTellL( fp );
    
    pszFileContents = (char *) VSIMalloc(nFileSize+1);
    if( pszFileContents == NULL )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, 
                  "Insufficient memory for loading XPM file %s into memory.", 
                  poOpenInfo->pszFilename );
        VSIFCloseL(fp);
        return NULL;
    }
    pszFileContents[nFileSize] = '\0';
    
    VSIFSeekL( fp, 0, SEEK_SET );

    if( VSIFReadL( pszFileContents, 1, nFileSize, fp ) != nFileSize)
    {
        CPLFree( pszFileContents );
        CPLError( CE_Failure, CPLE_FileIO, 
                  "Failed to read all %d bytes from file %s.",
                  nFileSize, poOpenInfo->pszFilename );
        VSIFCloseL(fp);
        return NULL;
    }
    
    VSIFCloseL(fp);
    fp = NULL;

/* -------------------------------------------------------------------- */
/*      Convert into a binary image.                                    */
/* -------------------------------------------------------------------- */
    GByte *pabyImage;
    int   nXSize, nYSize;
    GDALColorTable *poCT = NULL;

    CPLErrorReset();

    pabyImage = ParseXPM( pszFileContents, &nXSize, &nYSize, &poCT );
    CPLFree( pszFileContents );

    if( pabyImage == NULL )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    XPMDataset 	*poDS;

    poDS = new XPMDataset();

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    MEMRasterBand *poBand;

    poBand = new MEMRasterBand( poDS, 1, pabyImage, GDT_Byte, 1, nXSize, 
                                TRUE );
    poBand->SetColorTable( poCT );
    poDS->SetBand( 1, poBand );

    delete poCT;

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

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

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

{
/* -------------------------------------------------------------------- */
/*      Verify that this is some form of binterr file.                  */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 256)
        return NULL;

    if( strncmp( (const char *) poOpenInfo->pabyHeader, "binterr", 7 ) != 0 )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    BTDataset  *poDS;

    poDS = new BTDataset();
 
    memcpy( poDS->abyHeader, poOpenInfo->pabyHeader, 256 );

/* -------------------------------------------------------------------- */
/*      Get the version.                                                */
/* -------------------------------------------------------------------- */
    char szVersion[4];

    strncpy( szVersion, (char *) (poDS->abyHeader + 7), 3 );
    szVersion[3] = '\0';
    poDS->nVersionCode = (int) (atof(szVersion) * 10);

/* -------------------------------------------------------------------- */
/*      Extract core header information, being careful about the        */
/*      version.                                                        */
/* -------------------------------------------------------------------- */
    GInt32 nIntTemp;
    GInt16 nDataSize;
    GDALDataType eType;

    memcpy( &nIntTemp, poDS->abyHeader + 10, 4 );
    poDS->nRasterXSize = CPL_LSBWORD32( nIntTemp );
    
    memcpy( &nIntTemp, poDS->abyHeader + 14, 4 );
    poDS->nRasterYSize = CPL_LSBWORD32( nIntTemp );

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

    memcpy( &nDataSize, poDS->abyHeader+18, 2 );
    nDataSize = CPL_LSBWORD16( nDataSize );

    if( poDS->abyHeader[20] != 0 && nDataSize == 4 )
        eType = GDT_Float32;
    else if( poDS->abyHeader[20] == 0 && nDataSize == 4 )
        eType = GDT_Int32;
    else if( poDS->abyHeader[20] == 0 && nDataSize == 2 )
        eType = GDT_Int16;
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  ".bt file data type unknown, got datasize=%d.", 
                  nDataSize );
        delete poDS;
        return NULL;
    }

    /*
        rcg, apr 7/06: read offset 62 for vert. units.
        If zero, assume 1.0 as per spec.

    */
    memcpy( &poDS->m_fVscale, poDS->abyHeader + 62, 4 );
    CPL_LSBPTR32(&poDS->m_fVscale);
    if(poDS->m_fVscale == 0.0f)
        poDS->m_fVscale = 1.0f; 

/* -------------------------------------------------------------------- */
/*      Try to read a .prj file if it is indicated.                     */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS;						

    if( poDS->nVersionCode >= 12 && poDS->abyHeader[60] != 0 )
    {
        const char  *pszPrjFile = CPLResetExtension( poOpenInfo->pszFilename, 
                                                     "prj" );
        VSILFILE *fp;

        fp = VSIFOpenL( pszPrjFile, "rt" );
        if( fp != NULL )
        {
            char *pszBuffer, *pszBufPtr;
            int  nBufMax = 10000;
            int nBytes;

            pszBuffer = (char *) CPLMalloc(nBufMax);
            nBytes = VSIFReadL( pszBuffer, 1, nBufMax-1, fp );
            VSIFCloseL( fp );

            pszBuffer[nBytes] = '\0';

            pszBufPtr = pszBuffer;
            if( oSRS.importFromWkt( &pszBufPtr ) != OGRERR_NONE )
            {
                CPLError( CE_Warning, CPLE_AppDefined, 
                          "Unable to parse .prj file, coordinate system missing." );
            }
            CPLFree( pszBuffer );
        }
    }

/* -------------------------------------------------------------------- */
/*      If we didn't find a .prj file, try to use internal info.        */
/* -------------------------------------------------------------------- */
    if( oSRS.GetRoot() == NULL )
    {
        GInt16 nUTMZone, nDatum, nHUnits;
        
        memcpy( &nUTMZone, poDS->abyHeader + 24, 2 );
        nUTMZone = CPL_LSBWORD16( nUTMZone );
        
        memcpy( &nDatum, poDS->abyHeader + 26, 2 );
        nDatum = CPL_LSBWORD16( nDatum );
        
        memcpy( &nHUnits, poDS->abyHeader + 22, 2 );
        nHUnits = CPL_LSBWORD16( nHUnits );

        if( nUTMZone != 0 )
            oSRS.SetUTM( ABS(nUTMZone), nUTMZone > 0 );
        else if( nHUnits != 0 )
            oSRS.SetLocalCS( "Unknown" );
        
        if( nHUnits == 1 )
            oSRS.SetLinearUnits( SRS_UL_METER, 1.0 );
        else if( nHUnits == 2 )
            oSRS.SetLinearUnits( SRS_UL_FOOT, atof(SRS_UL_FOOT_CONV) );
        else if( nHUnits == 3 )
            oSRS.SetLinearUnits( SRS_UL_US_FOOT, atof(SRS_UL_US_FOOT_CONV) );

        // Translate some of the more obvious old USGS datum codes 
        if( nDatum == 0 )
            nDatum = 6201;
        else if( nDatum == 1 )
            nDatum = 6209;
        else if( nDatum == 2 )
            nDatum = 6210;
        else if( nDatum == 3 )
            nDatum = 6202;
        else if( nDatum == 4 )
            nDatum = 6203;
        else if( nDatum == 6 )
            nDatum = 6222;
        else if( nDatum == 7 )
            nDatum = 6230;
        else if( nDatum == 13 )
            nDatum = 6267;
        else if( nDatum == 14 )
            nDatum = 6269;
        else if( nDatum == 17 )
            nDatum = 6277;
        else if( nDatum == 19 )
            nDatum = 6284;
        else if( nDatum == 21 )
            nDatum = 6301;
        else if( nDatum == 22 )
            nDatum = 6322;
        else if( nDatum == 23 )
            nDatum = 6326;

        if( !oSRS.IsLocal() )
        {
            if( nDatum >= 6000 )
            {
                char szName[32];
                sprintf( szName, "EPSG:%d", nDatum-2000 );
                oSRS.SetWellKnownGeogCS( szName );
            }
            else
                oSRS.SetWellKnownGeogCS( "WGS84" );
        }                
    }

/* -------------------------------------------------------------------- */
/*      Convert coordinate system back to WKT.                          */
/* -------------------------------------------------------------------- */
    if( oSRS.GetRoot() != NULL )
        oSRS.exportToWkt( &poDS->pszProjection );

/* -------------------------------------------------------------------- */
/*      Get georeferencing bounds.                                      */
/* -------------------------------------------------------------------- */
    if( poDS->nVersionCode >= 11 )
    {
        double dfLeft, dfRight, dfTop, dfBottom;

        memcpy( &dfLeft, poDS->abyHeader + 28, 8 );
        CPL_LSBPTR64( &dfLeft );
        
        memcpy( &dfRight, poDS->abyHeader + 36, 8 );
        CPL_LSBPTR64( &dfRight );
        
        memcpy( &dfBottom, poDS->abyHeader + 44, 8 );
        CPL_LSBPTR64( &dfBottom );
        
        memcpy( &dfTop, poDS->abyHeader + 52, 8 );
        CPL_LSBPTR64( &dfTop );

        poDS->adfGeoTransform[0] = dfLeft;
        poDS->adfGeoTransform[1] = (dfRight - dfLeft) / poDS->nRasterXSize;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfTop;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = (dfBottom - dfTop) / poDS->nRasterYSize;
        
        poDS->bGeoTransformValid = TRUE;
    }
    
/* -------------------------------------------------------------------- */
/*      Re-open the file with the desired access.                       */
/* -------------------------------------------------------------------- */

    if( poOpenInfo->eAccess == GA_Update )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to re-open %s within BT driver.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }
    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Create band information objects                                 */
/* -------------------------------------------------------------------- */
    poDS->SetBand( 1, new BTRasterBand( poDS, poDS->fpImage, eType ) );

#ifdef notdef
    poDS->bGeoTransformValid = 
        GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", 
                           poDS->adfGeoTransform );
#endif

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

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

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

{
    if( !Identify(poOpenInfo) )
        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 = VSIFOpenL( 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( 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 );
        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. 12
0
GDALDataset *LCPDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Verify that this is a FARSITE LCP file    */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;
        
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The LCP driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    LCPDataset  *poDS;
    VSILFILE        *fpImage;

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

    poDS = new LCPDataset();
    poDS->fpImage = fpImage;

/* -------------------------------------------------------------------- */
/*      Read the header and extract some information.                   */
/* -------------------------------------------------------------------- */
   int bHaveCrownFuels, bHaveGroundFuels;
   int nBands, i;
   long nWidth = -1, nHeight = -1;
   int nTemp, nTemp2;
   char szTemp[32];
   char* pszList;

   VSIFSeekL( poDS->fpImage, 0, SEEK_SET );
   if (VSIFReadL( poDS->pachHeader, 1, LCP_HEADER_SIZE, poDS->fpImage ) != LCP_HEADER_SIZE)
   {
       CPLError(CE_Failure, CPLE_FileIO, "File too short");
       delete poDS;
       return NULL;
   }

   nWidth = CPL_LSBINT32PTR (poDS->pachHeader + 4164);
   nHeight = CPL_LSBINT32PTR (poDS->pachHeader + 4168);

   poDS->nRasterXSize = nWidth;
   poDS->nRasterYSize = nHeight;

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

   // crown fuels = canopy height, canopy base height, canopy bulk density
   // 21 = have them, 20 = don't have them
   bHaveCrownFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 0) - 20 );
   // ground fuels = duff loading, coarse woody
   bHaveGroundFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 4) - 20 );

   if( bHaveCrownFuels )
   {
       if( bHaveGroundFuels )
           nBands = 10;
       else
           nBands = 8;
   }
   else
   {
       if( bHaveGroundFuels )
           nBands = 7;
       else
           nBands = 5;
   }

   // add dataset-level metadata

   nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 8);
   sprintf(szTemp, "%d", nTemp);
   poDS->SetMetadataItem( "LATITUDE", szTemp );

   nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 4204);
   if ( nTemp == 0 )
      poDS->SetMetadataItem( "LINEAR_UNIT", "Meters" );
   if ( nTemp == 1 )
      poDS->SetMetadataItem( "LINEAR_UNIT", "Feet" );

   poDS->pachHeader[LCP_HEADER_SIZE-1] = '\0';
   poDS->SetMetadataItem( "DESCRIPTION", poDS->pachHeader + 6804 );


/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */

   int          iPixelSize;
   iPixelSize = nBands * 2;
   int          bNativeOrder;

   if (nWidth > INT_MAX / iPixelSize)
   {
       CPLError( CE_Failure, CPLE_AppDefined,  "Int overflow occured");
       delete poDS;
       return NULL;
   }

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

   pszList = (char*)CPLMalloc(2048);

   for( int iBand = 1; iBand <= nBands; iBand++ )
   {
        GDALRasterBand  *poBand = NULL;

        poBand = new RawRasterBand(
                     poDS, iBand, poDS->fpImage, LCP_HEADER_SIZE + ((iBand-1)*2),
                     iPixelSize, iPixelSize * nWidth, GDT_Int16, bNativeOrder, TRUE );

        poDS->SetBand(iBand, poBand);

        switch ( iBand ) {
        case 1:
           poBand->SetDescription("Elevation");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4224);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Meters" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Feet" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 44);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 48);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 52);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 4244 + 255) = '\0';
           poBand->SetMetadataItem( "ELEVATION_FILE", poDS->pachHeader + 4244 );

           break;

        case 2:
           poBand->SetDescription("Slope");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4226);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Degrees" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Percent" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 456);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 460);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 464);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 4500 + 255) = '\0';
           poBand->SetMetadataItem( "SLOPE_FILE", poDS->pachHeader + 4500 );

           break;

        case 3:
           poBand->SetDescription("Aspect");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4228);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass categories" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass degrees" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Azimuth degrees" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 868);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 872);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 876);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 4756 + 255) = '\0';
           poBand->SetMetadataItem( "ASPECT_FILE", poDS->pachHeader + 4756 );

           break;

        case 4:
           int nMinFM, nMaxFM;

           poBand->SetDescription("Fuel models");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4230);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "FUEL_MODEL_OPTION", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models AND no conversion file needed" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models BUT no conversion file needed" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models BUT conversion file needed" );
           if ( nTemp == 3 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models AND conversion file needed" );

           nMinFM = CPL_LSBINT32PTR (poDS->pachHeader + 1280);
           sprintf(szTemp, "%d", nMinFM);
           poBand->SetMetadataItem( "FUEL_MODEL_MIN", szTemp );

           nMaxFM = CPL_LSBINT32PTR (poDS->pachHeader + 1284);
           sprintf(szTemp, "%d", nMaxFM);
           poBand->SetMetadataItem( "FUEL_MODEL_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1288);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "FUEL_MODEL_NUM_CLASSES", szTemp );

           if (nTemp > 0 && nTemp <= 100) {
              strcpy(pszList, "");
              for ( i = 0; i <= nTemp; i++ ) {
                  nTemp2 = CPL_LSBINT32PTR (poDS->pachHeader + (1292+(i*4))) ;
                  if ( nTemp2 >= nMinFM && nTemp2 <= nMaxFM ) {
                     sprintf(szTemp, "%d", nTemp2);
                     strcat(pszList, szTemp);
                     if (i < (nTemp) )
                        strcat(pszList, ",");
                  }
              }
           }
           poBand->SetMetadataItem( "FUEL_MODEL_VALUES", pszList );

           *(poDS->pachHeader + 5012 + 255) = '\0';
           poBand->SetMetadataItem( "FUEL_MODEL_FILE", poDS->pachHeader + 5012 );

           break;

        case 5:
           poBand->SetDescription("Canopy cover");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4232);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Categories (0-4)" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Percent" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1692);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1696);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1700);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 5268 + 255) = '\0';
           poBand->SetMetadataItem( "CANOPY_COV_FILE", poDS->pachHeader + 5268 );

           break;

        case 6:
           if(bHaveCrownFuels) {
              poBand->SetDescription("Canopy height");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4234);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_UNIT", szTemp );

              if ( nTemp == 1 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters" );
              if ( nTemp == 2 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet" );
              if ( nTemp == 3 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters x 10" );
              if ( nTemp == 4 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet x 10" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2104);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2108);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2112);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 5524 + 255) = '\0';
              poBand->SetMetadataItem( "CANOPY_HT_FILE", poDS->pachHeader + 5524 );
           }
           else {
              poBand->SetDescription("Duff");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_UNIT", szTemp );

              if ( nTemp == 1 )
                 poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" );
              if ( nTemp == 2 )
                 poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 6292 + 255) = '\0';
              poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 );
           }
           break;

        case 7:
           if(bHaveCrownFuels) {
              poBand->SetDescription("Canopy base height");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4236);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_UNIT", szTemp );

              if ( nTemp == 1 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters" );
              if ( nTemp == 2 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet" );
              if ( nTemp == 3 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters x 10" );
              if ( nTemp == 4 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet x 10" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2516);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2520);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2524);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 5780 + 255) = '\0';
              poBand->SetMetadataItem( "CBH_FILE", poDS->pachHeader + 5780 );
           }
           else {
              poBand->SetDescription("Coarse woody debris");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_OPTION", szTemp );

              //if ( nTemp == 1 )
              //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );
              //if ( nTemp == 2 )
              //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 6548 + 255) = '\0';
              poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 );
           }
           break;

        case 8:
           poBand->SetDescription("Canopy bulk density");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4238);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_UNIT", szTemp );

           if ( nTemp == 1 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3" );
           if ( nTemp == 3 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3 x 100" );
           if ( nTemp == 4 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3 x 1000" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2928);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2932);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2936);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 6036 + 255) = '\0';
           poBand->SetMetadataItem( "CBD_FILE", poDS->pachHeader + 6036 );

           break;

        case 9:
           poBand->SetDescription("Duff");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_UNIT", szTemp );

           if ( nTemp == 1 )
              poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 6292 + 255) = '\0';
           poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 );

           break;

        case 10:
           poBand->SetDescription("Coarse woody debris");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_OPTION", szTemp );

           //if ( nTemp == 1 )
           //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );
           //if ( nTemp == 2 )
           //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 6548 + 255) = '\0';
           poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 );

           break;
        }
   }
   
/* -------------------------------------------------------------------- */
/*      Try to read projection file.                                    */
/* -------------------------------------------------------------------- */
    char        *pszDirname, *pszBasename;
    VSIStatBufL   sStatBuf;

    pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
    pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename));

    poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "prj" );
    int nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf );

    if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename))
    {
        poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "PRJ" );
        nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf );
    }

    if( nRet == 0 )
    {
        OGRSpatialReference     oSRS;

        char** papszPrj = CSLLoad( poDS->osPrjFilename );

        CPLDebug( "LCP", "Loaded SRS from %s", 
                  poDS->osPrjFilename.c_str() );

        if( oSRS.importFromESRI( papszPrj ) == OGRERR_NONE )
        {
            oSRS.exportToWkt( &(poDS->pszProjection) );
        }
        
        CSLDestroy(papszPrj);
    }

    CPLFree( pszDirname );
    CPLFree( pszBasename );

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

    CPLFree(pszList);

    return( poDS );
}
Esempio n. 13
0
static tsize_t
_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
{
    return VSIFReadL( buf, 1, size, (VSILFILE *) fd );
}
Esempio n. 14
0
GDALDataset *GS7BGDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( !Identify(poOpenInfo) )
    {
        return NULL;
    }

    /* ------------------------------------------------------------------- */
    /*      Create a corresponding GDALDataset.                            */
    /* ------------------------------------------------------------------- */
    GS7BGDataset    *poDS = new GS7BGDataset();

    /* ------------------------------------------------------------------- */
    /*      Open file with large file API.                                 */
    /* ------------------------------------------------------------------- */
    poDS->eAccess = poOpenInfo->eAccess;
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
        poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );

    if( poDS->fp == NULL )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_OpenFailed,
            "VSIFOpenL(%s) failed unexpectedly.",
            poOpenInfo->pszFilename );
        return NULL;
    }

    /* ------------------------------------------------------------------- */
    /*      Read the header. The Header section must be the first section  */
    /*      in the file.                                                   */
    /* ------------------------------------------------------------------- */
    if( VSIFSeekL( poDS->fp, 0, SEEK_SET ) != 0 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
                "Unable to seek to start of grid file header.\n" );
        return NULL;
    }

    GInt32 nTag;
    GInt32 nSize;
    GInt32 nVersion;

    if( VSIFReadL( (void *)&nTag, sizeof(GInt32), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO, "Unable to read Tag.\n" );
        return NULL;
    }

    CPL_LSBPTR32( &nTag );

    if(nTag != nHEADER_TAG)
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO, "Header tag not found.\n" );
        return NULL;
    }

    if( VSIFReadL( (void *)&nSize, sizeof(GInt32), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read file section size.\n" );
        return NULL;
    }

    CPL_LSBPTR32( &nSize );

    if( VSIFReadL( (void *)&nVersion, sizeof(GInt32), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read file version.\n" );
        return NULL;
    }

    CPL_LSBPTR32( &nVersion );

    if(nVersion != 1 && nVersion != 2)
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO, 
                  "Incorrect file version (%d).", nVersion );
        return NULL;
    }

    // advance until the grid tag is found
    while(nTag != nGRID_TAG)
    {
        if( VSIFReadL( (void *)&nTag, sizeof(GInt32), 1, poDS->fp ) != 1 )
        {
            delete poDS;
            CPLError( CE_Failure, CPLE_FileIO, "Unable to read Tag.\n" );
            return NULL;
        }

        CPL_LSBPTR32( &nTag );

        if( VSIFReadL( (void *)&nSize, sizeof(GInt32), 1, poDS->fp ) != 1 )
        {
            delete poDS;
            CPLError( CE_Failure, CPLE_FileIO,
                "Unable to read file section size.\n" );
            return NULL;
        }

        CPL_LSBPTR32( &nSize );

        if(nTag != nGRID_TAG)
        {
            if( VSIFSeekL( poDS->fp, nSize, SEEK_SET ) != 0 )
            {
                delete poDS;
                CPLError( CE_Failure, CPLE_FileIO,
                    "Unable to seek to end of file section.\n" );
                return NULL;
            }
        }
    }

    /* --------------------------------------------------------------------*/
    /*      Read the grid.                                                 */
    /* --------------------------------------------------------------------*/
    /* Parse number of Y axis grid rows */
    GInt32 nRows;
    if( VSIFReadL( (void *)&nRows, sizeof(GInt32), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read raster Y size.\n" );
        return NULL;
    }
    CPL_LSBPTR32( &nRows );
    poDS->nRasterYSize = nRows;

    /* Parse number of X axis grid columns */
    GInt32 nCols;
    if( VSIFReadL( (void *)&nCols, sizeof(GInt32), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read raster X size.\n" );
        return NULL;
    }
    CPL_LSBPTR32( &nCols );
    poDS->nRasterXSize = nCols;

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

    /* --------------------------------------------------------------------*/
    /*      Create band information objects.                               */
    /* --------------------------------------------------------------------*/
    GS7BGRasterBand *poBand = new GS7BGRasterBand( poDS, 1 );
    poDS->SetBand( 1, poBand );

    // find the min X Value of the grid
    double dfTemp;
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read minimum X value.\n" );
        return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMinX = dfTemp;

    // find the min Y value of the grid
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read minimum X value.\n" );
        return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMinY = dfTemp;

    // find the spacing between adjacent nodes in the X direction
    // (between columns)
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read spacing in X value.\n" );
        return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMaxX = poBand->dfMinX + (dfTemp * (nCols - 1));

    // find the spacing between adjacent nodes in the Y direction
    // (between rows)
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read spacing in Y value.\n" );
        return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMaxY = poBand->dfMinY + (dfTemp * (nRows - 1));

    // set the z min
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read Z min value.\n" );
        return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMinZ = dfTemp;

    // set the z max
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read Z max value.\n" );
        return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMaxZ = dfTemp;

    // read and ignore the rotation value
    //(This is not used in the current version).
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to read rotation value.\n" );
        return NULL;
    }

    // read and set the cell blank value
    if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to Blank value.\n" );
        return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poDS->dfNoData_Value = dfTemp;

    /* --------------------------------------------------------------------*/
    /*      Set the current offset of the grid data.                       */
    /* --------------------------------------------------------------------*/
    if( VSIFReadL( (void *)&nTag, sizeof(GInt32), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO, "Unable to read Tag.\n" );
        return NULL;
    }

    CPL_LSBPTR32( &nTag );
    if(nTag != nDATA_TAG)
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO, "Data tag not found.\n" );
        return NULL;
    }

    if( VSIFReadL( (void *)&nSize, sizeof(GInt32), 1, poDS->fp ) != 1 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_FileIO,
            "Unable to data section size.\n" );
        return NULL;
    }

    poDS->nData_Position = (size_t) VSIFTellL(poDS->fp);

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

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

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

{
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    KRODataset *poDS = new KRODataset();
    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Open the file.                                                  */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );

    if( poDS->fpImage == NULL )
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the file header.                                           */
/* -------------------------------------------------------------------- */
    char achHeader[20] = { '\0' };
    CPL_IGNORE_RET_VAL(VSIFReadL( achHeader, 1, 20, poDS->fpImage ));

    int nXSize;
    memcpy(&nXSize, achHeader + 4, 4);
    CPL_MSBPTR32( &nXSize );

    int nYSize = 0;
    memcpy(&nYSize, achHeader + 8, 4);
    CPL_MSBPTR32( &nYSize );

    int nDepth = 0;
    memcpy(&nDepth, achHeader + 12, 4);
    CPL_MSBPTR32( &nDepth );

    int nComp = 0;
    memcpy(&nComp, achHeader + 16, 4);
    CPL_MSBPTR32( &nComp );

    if( !GDALCheckDatasetDimensions(nXSize, nYSize) ||
        !GDALCheckBandCount(nComp, FALSE) )
    {
        delete poDS;
        return NULL;
    }

    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;

    GDALDataType eDT = GDT_Unknown;
    if( nDepth == 8 )
    {
        eDT = GDT_Byte;
    }
    else if( nDepth == 16 )
    {
        eDT = GDT_UInt16;
    }
    else if( nDepth == 32 )
    {
        eDT = GDT_Float32;
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unhandled depth : %d", nDepth );
        delete poDS;
        return NULL;
    }

    const int nDataTypeSize = nDepth / 8;

    if( nComp == 0 || nDataTypeSize == 0 ||
        poDS->nRasterXSize > INT_MAX / (nComp * nDataTypeSize) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Too large width / number of bands" );
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create bands.                                                   */
/* -------------------------------------------------------------------- */
    CPLErrorReset();
    for( int iBand = 0; iBand < nComp; iBand++ )
    {
        RawRasterBand *poBand =
            new RawRasterBand( poDS, iBand+1, poDS->fpImage,
                               20 + nDataTypeSize * iBand,
                               nComp * nDataTypeSize,
                               poDS->nRasterXSize * nComp * nDataTypeSize,
                               eDT, !CPL_IS_LSB, TRUE, FALSE );
        if( nComp == 3 || nComp == 4 )
        {
            poBand->SetColorInterpretation( (GDALColorInterp) (GCI_RedBand + iBand) );
        }
        poDS->SetBand( iBand+1, poBand );
        if( CPLGetLastErrorType() != CE_None )
        {
            delete poDS;
            return NULL;
        }
    }

    if( nComp > 1 )
        poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" );

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

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

    return poDS;
}
Esempio n. 16
0
int   NITFDESGetTRE( NITFDES* psDES,
                     int nOffset,
                     char szTREName[7],
                     char** ppabyTREData,
                     int* pnFoundTRESize)
{
    char szTREHeader[12];
    char szTRETempName[7];
    NITFSegmentInfo* psSegInfo;
    VSILFILE* fp;
    int nTRESize;

    memset(szTREName, '\0', 7);
    if (ppabyTREData)
        *ppabyTREData = NULL;
    if (pnFoundTRESize)
        *pnFoundTRESize = 0;

    if (nOffset < 0)
        return FALSE;

    if (psDES == NULL)
        return FALSE;

    if (CSLFetchNameValue(psDES->papszMetadata, "NITF_DESOFLW") == NULL)
        return FALSE;

    psSegInfo = psDES->psFile->pasSegmentInfo + psDES->iSegment;
    fp = psDES->psFile->fp;

    if (nOffset >= psSegInfo->nSegmentSize)
        return FALSE;

    VSIFSeekL(fp, psSegInfo->nSegmentStart + nOffset, SEEK_SET);

    if (VSIFReadL(szTREHeader, 1, 11, fp) != 11)
    {
        /* Some files have a nSegmentSize larger than what is is in reality */
        /* So exit silently if we're at end of file */ 
        VSIFSeekL(fp, 0, SEEK_END);
        if (VSIFTellL(fp) == psSegInfo->nSegmentStart + nOffset)
            return FALSE;

        CPLError(CE_Failure, CPLE_FileIO,
                 "Cannot get 11 bytes at offset " CPL_FRMT_GUIB ".",
                 psSegInfo->nSegmentStart + nOffset );
        return FALSE;
    }
    szTREHeader[11] = '\0';

    memcpy(szTRETempName, szTREHeader, 6);
    szTRETempName[6] = '\0';

    nTRESize = atoi(szTREHeader + 6);
    if (nTRESize < 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Invalid size (%d) for TRE %s",
                 nTRESize, szTRETempName);
        return FALSE;
    }
    if (nOffset + 11 + nTRESize > psSegInfo->nSegmentSize)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot read %s TRE. Not enough bytes : remaining %d, expected %d",
                 szTRETempName,
                 (int)(psSegInfo->nSegmentSize - (nOffset + 11)), nTRESize);
        return FALSE;
    }

    if (ppabyTREData)
    {
        /* Allocate one extra byte for the NULL terminating character */
        *ppabyTREData = (char*) VSIMalloc(nTRESize + 1);
        if (*ppabyTREData  == NULL)
        {
            CPLError(CE_Failure, CPLE_OutOfMemory,
                    "Cannot allocate %d bytes for TRE %s",
                    nTRESize, szTRETempName);
            return FALSE;
        }
        (*ppabyTREData)[nTRESize] = '\0';

        if ((int)VSIFReadL(*ppabyTREData, 1, nTRESize, fp) != nTRESize)
        {
            CPLError(CE_Failure, CPLE_FileIO,
                     "Cannot get %d bytes at offset " CPL_FRMT_GUIB ".",
                     nTRESize, VSIFTellL(fp) );
            VSIFree(*ppabyTREData);
            *ppabyTREData = NULL;
            return FALSE;
        }
    }

    strcpy(szTREName, szTRETempName);
    if (pnFoundTRESize)
        *pnFoundTRESize = nTRESize;

    return TRUE;
}
Esempio n. 17
0
int VICARKeywordHandler::Ingest( VSILFILE *fp, GByte *pabyHeader )

{
/* -------------------------------------------------------------------- */
/*      Read in buffer till we find END all on it's own line.           */
/* -------------------------------------------------------------------- */
    if( VSIFSeekL( fp, 0, SEEK_SET ) != 0 )
        return FALSE;

    // Find LBLSIZE Entry
    char* pszLBLSIZE = strstr((char*)pabyHeader,"LBLSIZE");
    int nOffset = 0;

    if (pszLBLSIZE)
        nOffset = pszLBLSIZE - (const char *)pabyHeader;

    char *pch1 = strstr((char*)pabyHeader+nOffset, "=");
    if( pch1 == NULL )
        return FALSE;

    ++pch1;
    char *pch2 = strstr((char*)pabyHeader+nOffset, " ");
    if( pch2 == NULL )
        return FALSE;

    char keyval[100];
    strncpy( keyval, pch1, MAX( pch2-pch1, 99 ) );
    keyval[MAX(pch2-pch1, 99)] = '\0';
    LabelSize = atoi( keyval );
    if( LabelSize > 10 * 1024 * 124 )
        return FALSE;

    char* pszChunk = (char*) VSIMalloc( LabelSize + 1 );
    if( pszChunk == NULL )
        return FALSE;
    int nBytesRead = VSIFReadL( pszChunk, 1, LabelSize, fp );
    pszChunk[LabelSize] = 0;

    osHeaderText += pszChunk ;
    VSIFree( pszChunk );
    pszHeaderNext = osHeaderText.c_str();

/* -------------------------------------------------------------------- */
/*      Process name/value pairs, keeping track of a "path stack".      */
/* -------------------------------------------------------------------- */
    if( !ReadGroup("") )
        return FALSE;
/* -------------------------------------------------------------------- */
/*      Now check for the Vicar End-of-Dataset Label...                 */
/* -------------------------------------------------------------------- */
    const char *pszResult = CSLFetchNameValue( papszKeywordList, "EOL" );
    if( pszResult == NULL )
        return FALSE;

    if( !EQUAL(pszResult,"1") )
        return TRUE;

/* -------------------------------------------------------------------- */
/*      There is a EOL!   e.G.  h4231_0000.nd4.06                       */
/* -------------------------------------------------------------------- */

    long int nPixelOffset=0;
    if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "BYTE" )) {
        nPixelOffset = 1;
    }
    else if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "HALF" )) {
        nPixelOffset = 2;
    }
    else if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "FULL" )) {
        nPixelOffset = 4;
    }
    else if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "REAL" )) {
        nPixelOffset = 4;
    }

    const long int nCols = atoi( CSLFetchNameValue( papszKeywordList, "NS" ) );
    const long int nRows = atoi( CSLFetchNameValue( papszKeywordList, "NL" ) );
    const int nBands = atoi( CSLFetchNameValue( papszKeywordList, "NB" ) );
    const int nBB = atoi( CSLFetchNameValue( papszKeywordList, "NBB" ) );

    long int nLineOffset = nPixelOffset * nCols + nBB ;
    long int nBandOffset = nLineOffset * nRows;

    long int starteol = LabelSize + nBandOffset * nBands;
    if( VSIFSeekL( fp, starteol, SEEK_SET ) != 0 )
    {
        printf("Error seeking to EOL!\n");
        return FALSE;
    }
    char szChunk[100];
    nBytesRead = VSIFReadL( szChunk, 1, 30, fp );
    szChunk[nBytesRead] = '\0';
    pszLBLSIZE = strstr( szChunk, "LBLSIZE" );
    nOffset = 0;

    if (pszLBLSIZE)
        nOffset = pszLBLSIZE - (const char *)szChunk;
    pch1 = strstr( (char*)szChunk + nOffset,"=" ) + 1;
    pch2 = strstr( (char*)szChunk + nOffset, " " );
    strncpy( keyval, pch1, pch2-pch1 );

    int EOLabelSize = atoi( keyval );
    if( EOLabelSize > 99 )
        EOLabelSize = 99;
    if( VSIFSeekL( fp, starteol, SEEK_SET ) != 0 )
    {
        printf("Error seeking again to EOL!\n");
        return FALSE;
    }

    nBytesRead = VSIFReadL( szChunk, 1, EOLabelSize, fp );
    szChunk[nBytesRead] = '\0';
    osHeaderText += szChunk ;
    osHeaderText.append("END");
    pszHeaderNext = osHeaderText.c_str();

    return ReadGroup( "" );
}
Esempio n. 18
0
NITFDES *NITFDESAccess( NITFFile *psFile, int iSegment )

{
    NITFDES   *psDES;
    char      *pachHeader;
    NITFSegmentInfo *psSegInfo;
    char       szDESID[26];
    int        nOffset;
    int        bHasDESOFLW;
    int        nDESSHL;
    
/* -------------------------------------------------------------------- */
/*      Verify segment, and return existing DES accessor if there       */
/*      is one.                                                         */
/* -------------------------------------------------------------------- */
    if( iSegment < 0 || iSegment >= psFile->nSegmentCount )
        return NULL;

    psSegInfo = psFile->pasSegmentInfo + iSegment;

    if( !EQUAL(psSegInfo->szSegmentType,"DE") )
        return NULL;

    if( psSegInfo->hAccess != NULL )
        return (NITFDES *) psSegInfo->hAccess;

/* -------------------------------------------------------------------- */
/*      Read the DES subheader.                                         */
/* -------------------------------------------------------------------- */
    if (psSegInfo->nSegmentHeaderSize < 200)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                    "DES header too small");
        return NULL;
    }

    pachHeader = (char*) VSIMalloc(psSegInfo->nSegmentHeaderSize);
    if (pachHeader == NULL)
    {
        CPLError(CE_Failure, CPLE_OutOfMemory,
                 "Cannot allocate memory for segment header");
        return NULL;
    }

retry:
    if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentHeaderStart, 
                  SEEK_SET ) != 0 
        || VSIFReadL( pachHeader, 1, psSegInfo->nSegmentHeaderSize, 
                     psFile->fp ) != psSegInfo->nSegmentHeaderSize )
    {
        CPLError( CE_Failure, CPLE_FileIO, 
                  "Failed to read %u byte DES subheader from " CPL_FRMT_GUIB ".",
                  psSegInfo->nSegmentHeaderSize,
                  psSegInfo->nSegmentHeaderStart );
        CPLFree(pachHeader);
        return NULL;
    }

    if (!EQUALN(pachHeader, "DE", 2))
    {
        if (EQUALN(pachHeader + 4, "DERegistered", 12))
        {
            /* BAO_46_Ed1/rpf/conc/concz10/000fz010.ona and cie are buggy */
            CPLDebug("NITF", "Patching nSegmentHeaderStart and nSegmentStart for DE segment %d", iSegment);
            psSegInfo->nSegmentHeaderStart += 4;
            psSegInfo->nSegmentStart += 4;
            goto retry;
        }

        CPLError(CE_Failure, CPLE_AppDefined,
                 "Invalid segment prefix for DE segment %d", iSegment);

        CPLFree(pachHeader);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Initialize DES object.                                          */
/* -------------------------------------------------------------------- */
    psDES = (NITFDES *) CPLCalloc(sizeof(NITFDES),1);

    psDES->psFile = psFile;
    psDES->iSegment = iSegment;
    psDES->pachHeader = pachHeader;

    psSegInfo->hAccess = psDES;

/* -------------------------------------------------------------------- */
/*      Collect a variety of information as metadata.                   */
/* -------------------------------------------------------------------- */
#define GetMD( length, name )              \
    do { NITFExtractMetadata( &(psDES->papszMetadata), pachHeader,    \
                         nOffset, length,                        \
                         "NITF_" #name ); \
    nOffset += length; } while(0)

    nOffset = 2;
    GetMD( 25, DESID  );
    GetMD(  2, DESVER );
    GetMD(  1, DECLAS );
    GetMD(  2, DESCLSY );
    GetMD( 11, DESCODE );
    GetMD(  2, DESCTLH );
    GetMD( 20, DESREL  );
    GetMD(  2, DESDCTP );
    GetMD(  8, DESDCDT );
    GetMD(  4, DESDCXM );
    GetMD(  1, DESDG   );
    GetMD(  8, DESDGDT );
    GetMD( 43, DESCLTX );
    GetMD(  1, DESCATP );
    GetMD( 40, DESCAUT );
    GetMD(  1, DESCRSN );
    GetMD(  8, DESSRDT );
    GetMD( 15, DESCTLN );

    /* Load DESID */
    NITFGetField( szDESID, pachHeader, 2, 25);

    /* For NITF < 02.10, we cannot rely on DESID=TRE_OVERFLOW to detect */
    /* if DESOFLW and DESITEM are present. So if the next 4 bytes are non */
    /* numeric, we'll assume that DESOFLW is there */
    bHasDESOFLW = EQUALN(szDESID, "TRE_OVERFLOW", strlen("TRE_OVERFLOW")) ||
       (!((pachHeader[nOffset+0] >= '0' && pachHeader[nOffset+0] <= '9') &&
          (pachHeader[nOffset+1] >= '0' && pachHeader[nOffset+1] <= '9') &&
          (pachHeader[nOffset+2] >= '0' && pachHeader[nOffset+2] <= '9') &&
          (pachHeader[nOffset+3] >= '0' && pachHeader[nOffset+3] <= '9')));

    if (bHasDESOFLW)
    {
        if ((int)psSegInfo->nSegmentHeaderSize < nOffset + 6 + 3 )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                        "DES header too small");
            NITFDESDeaccess(psDES);
            return NULL;
        }
        GetMD(  6, DESOFLW );
        GetMD(  3, DESITEM );
    }

    if ((int)psSegInfo->nSegmentHeaderSize < nOffset + 4 )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                    "DES header too small");
        NITFDESDeaccess(psDES);
        return NULL;
    }

    GetMD( 4, DESSHL );
    nDESSHL = atoi(CSLFetchNameValue( psDES->papszMetadata, "NITF_DESSHL" ) );

    if (nDESSHL < 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                    "Invalid value for DESSHL");
        NITFDESDeaccess(psDES);
        return NULL;
    }
    if ( (int)psSegInfo->nSegmentHeaderSize < nOffset + nDESSHL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                    "DES header too small");
        NITFDESDeaccess(psDES);
        return NULL;
    }

    if (EQUALN(szDESID, "CSSHPA DES", strlen("CSSHPA DES")))
    {
        if ( nDESSHL != 62 && nDESSHL != 80)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Invalid DESSHL for CSSHPA DES");
            NITFDESDeaccess(psDES);
            return NULL;
        }

        GetMD( 25, SHAPE_USE );
        GetMD( 10, SHAPE_CLASS );
        if (nDESSHL == 80)
            GetMD( 18, CC_SOURCE );
        GetMD(  3, SHAPE1_NAME );
        GetMD(  6, SHAPE1_START );
        GetMD(  3, SHAPE2_NAME );
        GetMD(  6, SHAPE2_START );
        GetMD(  3, SHAPE3_NAME );
        GetMD(  6, SHAPE3_START );
    }
    else if (EQUALN(szDESID, "XML_DATA_CONTENT", strlen("XML_DATA_CONTENT")))
    {
        /* TODO : handle nDESSHL = 0005 and 0283 */
        if (nDESSHL >= 5)
        {
            GetMD( 5, DESCRC );
            if (nDESSHL >= 283)
            {
                GetMD( 8, DESSHFT );
                GetMD( 20, DESSHDT );
                GetMD( 40, DESSHRP );
                GetMD( 60, DESSHSI );
                GetMD( 10, DESSHSV );
                GetMD( 20, DESSHSD );
                GetMD( 120, DESSHTN );
                if (nDESSHL >= 773)
                {
                    GetMD( 125, DESSHLPG );
                    GetMD( 25, DESSHLPT );
                    GetMD( 20, DESSHLI );
                    GetMD( 120, DESSHLIN );
                    GetMD( 200, DESSHABS );
                }
            }
        }
    }
    else if (EQUALN(szDESID, "CSATTA DES", strlen("CSATTA DES")) && nDESSHL == 52)
    {
        GetMD( 12, ATT_TYPE );
        GetMD( 14, DT_ATT );
        GetMD( 8, DATE_ATT );
        GetMD( 13, T0_ATT );
        GetMD( 5, NUM_ATT );
    }
    else if (nDESSHL > 0)
        GetMD(  nDESSHL, DESSHF );

    if ((int)psSegInfo->nSegmentHeaderSize > nOffset)
    {
        char* pszEscapedDESDATA =
                CPLEscapeString( pachHeader + nOffset, 
                                 (int)psSegInfo->nSegmentHeaderSize - nOffset, 
                                 CPLES_BackslashQuotable );
        psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata,
                                                "NITF_DESDATA",
                                                pszEscapedDESDATA );
        CPLFree(pszEscapedDESDATA);
    }
    else
    {
        char* pachData = (char*)VSIMalloc((size_t)psSegInfo->nSegmentSize);
        if (pachData == NULL )
        {
            CPLDebug("NITF", "Cannot allocate " CPL_FRMT_GUIB " bytes DES data",
                     psSegInfo->nSegmentSize);
        }
        else if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentStart,
                    SEEK_SET ) != 0
            || VSIFReadL( pachData, 1, (size_t)psSegInfo->nSegmentSize,
                        psFile->fp ) != psSegInfo->nSegmentSize )
        {
            CPLDebug("NITF",
                    "Failed to read " CPL_FRMT_GUIB" bytes DES data from " CPL_FRMT_GUIB ".",
                    psSegInfo->nSegmentSize,
                    psSegInfo->nSegmentStart );
        }
        else
        {
            char* pszEscapedDESDATA =
                    CPLEscapeString( pachData,
                                    (int)psSegInfo->nSegmentSize,
                                    CPLES_BackslashQuotable );
            psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata,
                                                    "NITF_DESDATA",
                                                    pszEscapedDESDATA );
            CPLFree(pszEscapedDESDATA);
        }

#ifdef notdef
        /* Disabled because might generate a huge amount of elements */
        if (EQUALN(szDESID, "CSATTA DES", strlen("CSATTA DES")))
        {
            int nNumAtt = atoi(CSLFetchNameValueDef(psDES->papszMetadata, "NITF_NUM_ATT", "0"));
            if (nNumAtt * 8 * 4 == psSegInfo->nSegmentSize)
            {
                int nMDSize = CSLCount(psDES->papszMetadata);
                char** papszMD = (char**)VSIRealloc(psDES->papszMetadata, (nMDSize + nNumAtt * 4 + 1) * sizeof(char*));
                if (papszMD)
                {
                    int i, j;
                    const GByte* pachDataIter = pachData;

                    psDES->papszMetadata = papszMD;
                    for(i=0;i<nNumAtt;i++)
                    {
                        char szAttrNameValue[64+1+256+1];
                        double dfVal;
                        for(j=0;j<4;j++)
                        {
                            memcpy(&dfVal, pachDataIter, 8);
                            CPL_MSBPTR64(&dfVal);
                            pachDataIter += 8;
                            sprintf(szAttrNameValue, "NITF_ATT_Q%d_%d=%.16g", j+1, i, dfVal);
                            papszMD[nMDSize + i * 4 + j] = CPLStrdup(szAttrNameValue);
                        }
                    }
                    papszMD[nMDSize + nNumAtt * 4] = NULL;
                }
            }
        }
#endif

        CPLFree(pachData);
    }

    return psDES;
}
Esempio n. 19
0
GDALDataset *HF2Dataset::Open( GDALOpenInfo * poOpenInfo )

{
    CPLString osOriginalFilename(poOpenInfo->pszFilename);

    if (!Identify(poOpenInfo))
        return NULL;

    GDALOpenInfo* poOpenInfoToDelete = NULL;
    /*  GZipped .hf2 files are common, so automagically open them */
    /*  if the /vsigzip/ has not been explicitely passed */
    CPLString osFilename(poOpenInfo->pszFilename);
    if ((EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "hfz") ||
        (strlen(poOpenInfo->pszFilename) > 6 &&
         EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "hf2.gz"))) &&
         !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
    {
        osFilename = "/vsigzip/";
        osFilename += poOpenInfo->pszFilename;
        poOpenInfo = poOpenInfoToDelete =
                new GDALOpenInfo(osFilename.c_str(), GA_ReadOnly,
                                 poOpenInfo->papszSiblingFiles);
    }

/* -------------------------------------------------------------------- */
/*      Parse header                                                    */
/* -------------------------------------------------------------------- */

    int nXSize, nYSize;
    memcpy(&nXSize, poOpenInfo->pabyHeader + 6, 4);
    CPL_LSBPTR32(&nXSize);
    memcpy(&nYSize, poOpenInfo->pabyHeader + 10, 4);
    CPL_LSBPTR32(&nYSize);

    GUInt16 nTileSize;
    memcpy(&nTileSize, poOpenInfo->pabyHeader + 14, 2);
    CPL_LSBPTR16(&nTileSize);

    float fVertPres, fHorizScale;
    memcpy(&fVertPres, poOpenInfo->pabyHeader + 16, 4);
    CPL_LSBPTR32(&fVertPres);
    memcpy(&fHorizScale, poOpenInfo->pabyHeader + 20, 4);
    CPL_LSBPTR32(&fHorizScale);

    GUInt32 nExtendedHeaderLen;
    memcpy(&nExtendedHeaderLen, poOpenInfo->pabyHeader + 24, 4);
    CPL_LSBPTR32(&nExtendedHeaderLen);

    delete poOpenInfoToDelete;
    poOpenInfoToDelete = NULL;

    if (nTileSize < 8)
        return NULL;
    if (nXSize <= 0 || nXSize > INT_MAX - nTileSize ||
        nYSize <= 0 || nYSize > INT_MAX - nTileSize)
        return NULL;
    /* To avoid later potential int overflows */
    if (nExtendedHeaderLen > 1024 * 65536)
        return NULL;

    if (!GDALCheckDatasetDimensions(nXSize, nYSize))
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Parse extended blocks                                           */
/* -------------------------------------------------------------------- */

    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    VSIFSeekL(fp, 28, SEEK_SET);

    int bHasExtent = FALSE;
    double dfMinX = 0, dfMaxX = 0, dfMinY = 0, dfMaxY = 0;
    int bHasUTMZone = FALSE;
    GInt16 nUTMZone = 0;
    int bHasEPSGDatumCode = FALSE;
    GInt16 nEPSGDatumCode = 0;
    int bHasEPSGCode = FALSE;
    GInt16 nEPSGCode = 0;
    int bHasRelativePrecision = FALSE;
    float fRelativePrecision = 0;
    char szApplicationName[256];
    szApplicationName[0] = 0;

    GUInt32 nExtendedHeaderOff = 0;
    while(nExtendedHeaderOff < nExtendedHeaderLen)
    {
        char pabyBlockHeader[24];
        VSIFReadL(pabyBlockHeader, 24, 1, fp);

        char szBlockName[16 + 1];
        memcpy(szBlockName, pabyBlockHeader + 4, 16);
        szBlockName[16] = 0;
        GUInt32 nBlockSize;
        memcpy(&nBlockSize, pabyBlockHeader + 20, 4);
        CPL_LSBPTR32(&nBlockSize);
        if (nBlockSize > 65536)
            break;

        nExtendedHeaderOff += 24 + nBlockSize;

        if (strcmp(szBlockName, "georef-extents") == 0 &&
            nBlockSize == 34)
        {
            char pabyBlockData[34];
            VSIFReadL(pabyBlockData, 34, 1, fp);

            memcpy(&dfMinX, pabyBlockData + 2, 8);
            CPL_LSBPTR64(&dfMinX);
            memcpy(&dfMaxX, pabyBlockData + 2 + 8, 8);
            CPL_LSBPTR64(&dfMaxX);
            memcpy(&dfMinY, pabyBlockData + 2 + 8 + 8, 8);
            CPL_LSBPTR64(&dfMinY);
            memcpy(&dfMaxY, pabyBlockData + 2 + 8 + 8 + 8, 8);
            CPL_LSBPTR64(&dfMaxY);

            bHasExtent = TRUE;
        }
        else if (strcmp(szBlockName, "georef-utm") == 0 &&
                nBlockSize == 2)
        {
            VSIFReadL(&nUTMZone, 2, 1, fp);
            CPL_LSBPTR16(&nUTMZone);
            CPLDebug("HF2", "UTM Zone = %d", nUTMZone);

            bHasUTMZone = TRUE;
        }
        else if (strcmp(szBlockName, "georef-datum") == 0 &&
                 nBlockSize == 2)
        {
            VSIFReadL(&nEPSGDatumCode, 2, 1, fp);
            CPL_LSBPTR16(&nEPSGDatumCode);
            CPLDebug("HF2", "EPSG Datum Code = %d", nEPSGDatumCode);

            bHasEPSGDatumCode = TRUE;
        }
        else if (strcmp(szBlockName, "georef-epsg-prj") == 0 &&
                 nBlockSize == 2)
        {
            VSIFReadL(&nEPSGCode, 2, 1, fp);
            CPL_LSBPTR16(&nEPSGCode);
            CPLDebug("HF2", "EPSG Code = %d", nEPSGCode);

            bHasEPSGCode = TRUE;
        }
        else if (strcmp(szBlockName, "precis-rel") == 0 &&
                 nBlockSize == 4)
        {
            VSIFReadL(&fRelativePrecision, 4, 1, fp);
            CPL_LSBPTR32(&fRelativePrecision);

            bHasRelativePrecision = TRUE;
        }
        else if (strcmp(szBlockName, "app-name") == 0 &&
                 nBlockSize < 256)
        {
            VSIFReadL(szApplicationName, nBlockSize, 1, fp);
            szApplicationName[nBlockSize] = 0;
        }
        else
        {
            CPLDebug("HF2", "Skipping block %s", szBlockName);
            VSIFSeekL(fp, nBlockSize, SEEK_CUR);
        }
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    HF2Dataset         *poDS;

    poDS = new HF2Dataset();
    poDS->fp = fp;
    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;
    poDS->nTileSize = nTileSize;
    CPLDebug("HF2", "nXSize = %d, nYSize = %d, nTileSize = %d", nXSize, nYSize, nTileSize);
    if (bHasExtent)
    {
        poDS->adfGeoTransform[0] = dfMinX;
        poDS->adfGeoTransform[3] = dfMaxY;
        poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nXSize;
        poDS->adfGeoTransform[5] = -(dfMaxY - dfMinY) / nYSize;
    }
    else
    {
        poDS->adfGeoTransform[1] = fHorizScale;
        poDS->adfGeoTransform[5] = fHorizScale;
    }

    if (bHasEPSGCode)
    {
        OGRSpatialReference oSRS;
        if (oSRS.importFromEPSG(nEPSGCode) == OGRERR_NONE)
            oSRS.exportToWkt(&poDS->pszWKT);
    }
    else
    {
        int bHasSRS = FALSE;
        OGRSpatialReference oSRS;
        oSRS.SetGeogCS("unknown", "unknown", "unknown", SRS_WGS84_SEMIMAJOR, SRS_WGS84_INVFLATTENING); 
        if (bHasEPSGDatumCode)
        {
            if (nEPSGDatumCode == 23 || nEPSGDatumCode == 6326)
            {
                bHasSRS = TRUE;
                oSRS.SetWellKnownGeogCS("WGS84");
            }
            else if (nEPSGDatumCode >= 6000)
            {
                char szName[32];
                sprintf( szName, "EPSG:%d", nEPSGDatumCode-2000 );
                oSRS.SetWellKnownGeogCS( szName );
                bHasSRS = TRUE;
            }
        }

        if (bHasUTMZone && ABS(nUTMZone) >= 1 && ABS(nUTMZone) <= 60)
        {
            bHasSRS = TRUE;
            oSRS.SetUTM(ABS(nUTMZone), nUTMZone > 0);
        }
        if (bHasSRS)
            oSRS.exportToWkt(&poDS->pszWKT);
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    int i;
    for( i = 0; i < poDS->nBands; i++ )
    {
        poDS->SetBand( i+1, new HF2RasterBand( poDS, i+1, GDT_Float32 ) );
        poDS->GetRasterBand(i+1)->SetUnitType("m");
    }

    if (szApplicationName[0] != '\0')
        poDS->SetMetadataItem("APPLICATION_NAME", szApplicationName);
    poDS->SetMetadataItem("VERTICAL_PRECISION", CPLString().Printf("%f", fVertPres));
    if (bHasRelativePrecision)
        poDS->SetMetadataItem("RELATIVE_VERTICAL_PRECISION", CPLString().Printf("%f", fRelativePrecision));

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( osOriginalFilename.c_str() );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, osOriginalFilename.c_str() );
    return( poDS );
}
Esempio n. 20
0
int NITFDESExtractShapefile(NITFDES* psDES, const char* pszRadixFileName)
{
    NITFSegmentInfo* psSegInfo;
    const char* apszExt[3];
    int anOffset[4];
    int iShpFile;
    char* pszFilename;

    if ( CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE_USE") == NULL )
        return FALSE;

    psSegInfo = psDES->psFile->pasSegmentInfo + psDES->iSegment;

    apszExt[0] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE1_NAME");
    anOffset[0] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE1_START"));
    apszExt[1] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE2_NAME");
    anOffset[1] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE2_START"));
    apszExt[2] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE3_NAME");
    anOffset[2] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE3_START"));
    anOffset[3] = (int) psSegInfo->nSegmentSize;

    for(iShpFile = 0; iShpFile < 3; iShpFile ++)
    {
        if (!EQUAL(apszExt[iShpFile], "SHP") &&
            !EQUAL(apszExt[iShpFile], "SHX") &&
            !EQUAL(apszExt[iShpFile], "DBF"))
            return FALSE;

        if (anOffset[iShpFile] < 0 ||
            anOffset[iShpFile] >= anOffset[iShpFile+1])
            return FALSE;
    }

    pszFilename = (char*) VSIMalloc(strlen(pszRadixFileName) + 4 + 1);
    if (pszFilename == NULL)
        return FALSE;

    for(iShpFile = 0; iShpFile < 3; iShpFile ++)
    {
        VSILFILE* fp;
        GByte* pabyBuffer;
        int nSize = anOffset[iShpFile+1] - anOffset[iShpFile];

        pabyBuffer = (GByte*) VSIMalloc(nSize);
        if (pabyBuffer == NULL)
        {
            VSIFree(pszFilename);
            return FALSE;
        }

        VSIFSeekL(psDES->psFile->fp, psSegInfo->nSegmentStart + anOffset[iShpFile], SEEK_SET);
        if (VSIFReadL(pabyBuffer, 1, nSize, psDES->psFile->fp) != nSize)
        {
            VSIFree(pabyBuffer);
            VSIFree(pszFilename);
            return FALSE;
        }

        sprintf(pszFilename, "%s.%s", pszRadixFileName, apszExt[iShpFile]);
        fp = VSIFOpenL(pszFilename, "wb");
        if (fp == NULL)
        {
            VSIFree(pabyBuffer);
            VSIFree(pszFilename);
            return FALSE;
        }

        VSIFWriteL(pabyBuffer, 1, nSize, fp);
        VSIFCloseL(fp);
        VSIFree(pabyBuffer);
    }

    VSIFree(pszFilename);

    return TRUE;
}
Esempio n. 21
0
int main( int nArgc, char ** papszArgv )

{
    NITFFile	*psFile;
    int          iSegment, iFile;
    char         szTemp[100];
    int          bDisplayTRE = FALSE;
    int          bExtractSHP = FALSE, bExtractSHPInMem = FALSE;

    if( nArgc < 2 )
    {
        printf( "Usage: nitfdump [-tre] [-extractshp | -extractshpinmem] <nitf_filename>*\n" );
        exit( 1 );
    }

    for( iFile = 1; iFile < nArgc; iFile++ )
    {
        if ( EQUAL(papszArgv[iFile], "-tre") )
            bDisplayTRE = TRUE;
        else if ( EQUAL(papszArgv[iFile], "-extractshp") )
            bExtractSHP = TRUE;
        else if ( EQUAL(papszArgv[iFile], "-extractshpinmem") )
        {
            bExtractSHP = TRUE;
            bExtractSHPInMem = TRUE;
        }
    }

/* ==================================================================== */
/*      Loop over all files.                                            */
/* ==================================================================== */
    for( iFile = 1; iFile < nArgc; iFile++ )
    {
        int bHasFoundLocationTable = FALSE;

        if ( EQUAL(papszArgv[iFile], "-tre") )
            continue;
        if ( EQUAL(papszArgv[iFile], "-extractshp") )
            continue;
        if ( EQUAL(papszArgv[iFile], "-extractshpinmem") )
            continue;

/* -------------------------------------------------------------------- */
/*      Open the file.                                                  */
/* -------------------------------------------------------------------- */
        psFile = NITFOpen( papszArgv[iFile], FALSE );
        if( psFile == NULL )
            exit( 2 );

        printf( "Dump for %s\n", papszArgv[iFile] );

/* -------------------------------------------------------------------- */
/*      Dump first TRE list.                                            */
/* -------------------------------------------------------------------- */
        if( psFile->pachTRE != NULL )
        {
            int nTREBytes = psFile->nTREBytes;
            const char *pszTREData = psFile->pachTRE;


            printf( "File TREs:" );

            while( nTREBytes > 10 )
            {
                int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 ));
                if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11)
                {
                    NITFGetField(szTemp, pszTREData, 0, 6 );
                    printf(" Invalid size (%d) for TRE %s", nThisTRESize, szTemp);
                    break;
                }

                printf( " %6.6s(%d)", pszTREData, nThisTRESize );
                pszTREData += nThisTRESize + 11;
                nTREBytes -= (nThisTRESize + 11);
            }
            printf( "\n" );

            if (bDisplayTRE)
            {
                nTREBytes = psFile->nTREBytes;
                pszTREData = psFile->pachTRE;

                while( nTREBytes > 10 )
                {
                    char *pszEscaped;
                    int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 ));
                    if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11)
                    {
                        break;
                    }

                    pszEscaped = CPLEscapeString( pszTREData + 11, nThisTRESize,
                                                       CPLES_BackslashQuotable );
                    printf( "TRE '%6.6s' : %s\n", pszTREData, pszEscaped);
                    CPLFree(pszEscaped);

                    pszTREData += nThisTRESize + 11;
                    nTREBytes -= (nThisTRESize + 11);
                }
            }
        }

/* -------------------------------------------------------------------- */
/*      Dump Metadata                                                   */
/* -------------------------------------------------------------------- */
        DumpMetadata( "File Metadata:", "  ", psFile->papszMetadata );

/* -------------------------------------------------------------------- */
/*      Dump general info about segments.                               */
/* -------------------------------------------------------------------- */
        NITFCollectAttachments( psFile );
        NITFReconcileAttachments( psFile );

        for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ )
        {
            NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment;

            printf( "Segment %d (Type=%s):\n",
                    iSegment + 1, psSegInfo->szSegmentType );

            printf( "  HeaderStart=" CPL_FRMT_GUIB ", HeaderSize=%u, DataStart=" CPL_FRMT_GUIB ", DataSize=" CPL_FRMT_GUIB "\n",
                    psSegInfo->nSegmentHeaderStart,
                    psSegInfo->nSegmentHeaderSize,
                    psSegInfo->nSegmentStart,
                    psSegInfo->nSegmentSize );
            printf( "  DLVL=%d, ALVL=%d, LOC=C%d,R%d, CCS=C%d,R%d\n",
                    psSegInfo->nDLVL,
                    psSegInfo->nALVL,
                    psSegInfo->nLOC_C,
                    psSegInfo->nLOC_R,
                    psSegInfo->nCCS_C,
                    psSegInfo->nCCS_R );
            printf( "\n" );
        }

/* -------------------------------------------------------------------- */
/*      Report details of images.                                       */
/* -------------------------------------------------------------------- */
        for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ )
        {
            NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment;
            NITFImage *psImage;
            NITFRPC00BInfo sRPCInfo;
            int iBand;
            char **papszMD;

            if( !EQUAL(psSegInfo->szSegmentType,"IM") )
                continue;

            psImage = NITFImageAccess( psFile, iSegment );
            if( psImage == NULL )
            {
                printf( "NITFAccessImage(%d) failed!\n", iSegment );
                continue;
            }

            printf( "Image Segment %d, %dPx%dLx%dB x %dbits:\n",
                    iSegment + 1, psImage->nCols, psImage->nRows,
                    psImage->nBands, psImage->nBitsPerSample );
            printf( "  PVTYPE=%s, IREP=%s, ICAT=%s, IMODE=%c, IC=%s, COMRAT=%s, ICORDS=%c\n",
                    psImage->szPVType, psImage->szIREP, psImage->szICAT,
                    psImage->chIMODE, psImage->szIC, psImage->szCOMRAT,
                    psImage->chICORDS );
            if( psImage->chICORDS != ' ' )
            {
                printf( "  UL=(%.15g,%.15g), UR=(%.15g,%.15g) Center=%d\n  LL=(%.15g,%.15g), LR=(%.15g,%.15g)\n",
                        psImage->dfULX, psImage->dfULY,
                        psImage->dfURX, psImage->dfURY,
                        psImage->bIsBoxCenterOfPixel,
                        psImage->dfLLX, psImage->dfLLY,
                        psImage->dfLRX, psImage->dfLRY );
            }

            printf( "  IDLVL=%d, IALVL=%d, ILOC R=%d,C=%d, IMAG=%s\n",
                    psImage->nIDLVL, psImage->nIALVL,
                    psImage->nILOCRow, psImage->nILOCColumn,
                    psImage->szIMAG );

            printf( "  %d x %d blocks of size %d x %d\n",
                    psImage->nBlocksPerRow, psImage->nBlocksPerColumn,
                    psImage->nBlockWidth, psImage->nBlockHeight );

            if( psImage->pachTRE != NULL )
            {
                int nTREBytes = psImage->nTREBytes;
                const char *pszTREData = psImage->pachTRE;

                printf( "  Image TREs:" );

                while( nTREBytes > 10 )
                {
                    int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 ));
                    if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11)
                    {
                        NITFGetField(szTemp, pszTREData, 0, 6 );
                        printf(" Invalid size (%d) for TRE %s", nThisTRESize, szTemp);
                        break;
                    }

                    printf( " %6.6s(%d)", pszTREData, nThisTRESize );
                    pszTREData += nThisTRESize + 11;
                    nTREBytes -= (nThisTRESize + 11);
                }
                printf( "\n" );

                if (bDisplayTRE)
                {
                    nTREBytes = psImage->nTREBytes;
                    pszTREData = psImage->pachTRE;

                    while( nTREBytes > 10 )
                    {
                        char *pszEscaped;
                        int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 ));
                        if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11)
                        {
                            break;
                        }

                        pszEscaped = CPLEscapeString( pszTREData + 11, nThisTRESize,
                                                        CPLES_BackslashQuotable );
                        printf( "  TRE '%6.6s' : %s\n", pszTREData, pszEscaped);
                        CPLFree(pszEscaped);

                        pszTREData += nThisTRESize + 11;
                        nTREBytes -= (nThisTRESize + 11);
                    }
                }
            }

            /* Report info from location table, if found.                  */
            if( psImage->nLocCount > 0 )
            {
                int i;
                bHasFoundLocationTable = TRUE;
                printf( "  Location Table\n" );
                for( i = 0; i < psImage->nLocCount; i++ )
                {
                    printf( "    LocName=%s, LocId=%d, Offset=%u, Size=%u\n",
                            GetLocationNameFromId(psImage->pasLocations[i].nLocId),
                            psImage->pasLocations[i].nLocId,
                            psImage->pasLocations[i].nLocOffset,
                            psImage->pasLocations[i].nLocSize );
                }
                printf( "\n" );
            }

            if( strlen(psImage->pszComments) > 0 )
                printf( "  Comments:\n%s\n", psImage->pszComments );

            for( iBand = 0; iBand < psImage->nBands; iBand++ )
            {
                NITFBandInfo *psBandInfo = psImage->pasBandInfo + iBand;

                printf( "  Band %d: IREPBAND=%s, ISUBCAT=%s, %d LUT entries.\n",
                        iBand + 1, psBandInfo->szIREPBAND, psBandInfo->szISUBCAT,
                        psBandInfo->nSignificantLUTEntries );
            }

            if( NITFReadRPC00B( psImage, &sRPCInfo ) )
            {
                DumpRPC( psImage, &sRPCInfo );
            }

            papszMD = NITFReadUSE00A( psImage );
            if( papszMD != NULL )
            {
                DumpMetadata( "  USE00A TRE:", "    ", papszMD );
                CSLDestroy( papszMD );
            }

            papszMD = NITFReadBLOCKA( psImage );
            if( papszMD != NULL )
            {
                DumpMetadata( "  BLOCKA TRE:", "    ", papszMD );
                CSLDestroy( papszMD );
            }

            papszMD = NITFReadSTDIDC( psImage );
            if( papszMD != NULL )
            {
                DumpMetadata( "  STDIDC TRE:", "    ", papszMD );
                CSLDestroy( papszMD );
            }

            DumpMetadata( "  Image Metadata:", "    ", psImage->papszMetadata );
            printf("\n");
        }

/* ==================================================================== */
/*      Report details of graphic segments.                             */
/* ==================================================================== */
        for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ )
        {
            NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment;
            char achSubheader[298];
            int  nSTYPEOffset;

            if( !EQUAL(psSegInfo->szSegmentType,"GR")
                && !EQUAL(psSegInfo->szSegmentType,"SY") )
                continue;

/* -------------------------------------------------------------------- */
/*      Load the graphic subheader.                                     */
/* -------------------------------------------------------------------- */
            if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentHeaderStart,
                           SEEK_SET ) != 0
                || VSIFReadL( achSubheader, 1, sizeof(achSubheader),
                              psFile->fp ) < 258 )
            {
                CPLError( CE_Warning, CPLE_FileIO,
                          "Failed to read graphic subheader at " CPL_FRMT_GUIB ".",
                          psSegInfo->nSegmentHeaderStart );
                continue;
            }

            // NITF 2.0. (also works for NITF 2.1)
            nSTYPEOffset = 200;
            if( STARTS_WITH_CI(achSubheader+193, "999998") )
                nSTYPEOffset += 40;

/* -------------------------------------------------------------------- */
/*      Report some standard info.                                      */
/* -------------------------------------------------------------------- */
            printf( "Graphic Segment %d, type=%2.2s, sfmt=%c, sid=%10.10s\n",
                    iSegment + 1,
                    achSubheader + 0,
                    achSubheader[nSTYPEOffset],
                    achSubheader + 2 );

            printf( "  sname=%20.20s\n", achSubheader + 12 );
            printf("\n");
        }

/* ==================================================================== */
/*      Report details of text segments.                                */
/* ==================================================================== */
        for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ )
        {
            char *pabyHeaderData;
            char *pabyTextData;

            NITFSegmentInfo *psSegment = psFile->pasSegmentInfo + iSegment;

            if( !EQUAL(psSegment->szSegmentType,"TX") )
                continue;

            printf( "Text Segment %d\n", iSegment + 1);

/* -------------------------------------------------------------------- */
/*      Load the text header                                            */
/* -------------------------------------------------------------------- */

            /* Allocate one extra byte for the NULL terminating character */
            pabyHeaderData = (char *) CPLCalloc(1,
                    (size_t) psSegment->nSegmentHeaderSize + 1);
            if (VSIFSeekL(psFile->fp, psSegment->nSegmentHeaderStart,
                        SEEK_SET) != 0 ||
                VSIFReadL(pabyHeaderData, 1, (size_t) psSegment->nSegmentHeaderSize,
                        psFile->fp) != psSegment->nSegmentHeaderSize)
            {
                CPLError( CE_Warning, CPLE_FileIO,
                        "Failed to read %d bytes of text header data at " CPL_FRMT_GUIB ".",
                        psSegment->nSegmentHeaderSize,
                        psSegment->nSegmentHeaderStart);
                CPLFree(pabyHeaderData);
                continue;
            }

            printf("  Header : %s\n", pabyHeaderData);
            CPLFree(pabyHeaderData);

/* -------------------------------------------------------------------- */
/*      Load the raw TEXT data itself.                                  */
/* -------------------------------------------------------------------- */


            /* Allocate one extra byte for the NULL terminating character */
            pabyTextData = (char *) CPLCalloc(1,(size_t)psSegment->nSegmentSize+1);
            if( VSIFSeekL( psFile->fp, psSegment->nSegmentStart,
                        SEEK_SET ) != 0
                || VSIFReadL( pabyTextData, 1, (size_t)psSegment->nSegmentSize,
                            psFile->fp ) != psSegment->nSegmentSize )
            {
                CPLError( CE_Warning, CPLE_FileIO,
                        "Failed to read " CPL_FRMT_GUIB " bytes of text data at " CPL_FRMT_GUIB ".",
                        psSegment->nSegmentSize,
                        psSegment->nSegmentStart );
                CPLFree( pabyTextData );
                continue;
            }

            printf("  Data  : %s\n", pabyTextData);
            printf("\n");
            CPLFree( pabyTextData );

        }

/* -------------------------------------------------------------------- */
/*      Report details of DES.                                          */
/* -------------------------------------------------------------------- */
        for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ )
        {
            NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment;
            NITFDES *psDES;
            int nOffset = 0;
            char szTREName[7];
            int nThisTRESize;
            int nRPFDESOffset = -1;

            if( !EQUAL(psSegInfo->szSegmentType,"DE") )
                continue;

            psDES = NITFDESAccess( psFile, iSegment );
            if( psDES == NULL )
            {
                printf( "NITFDESAccess(%d) failed!\n", iSegment );
                continue;
            }

            printf( "DE Segment %d:\n", iSegment + 1 );

            printf( "  Segment TREs:" );
            nOffset = 0;
            while (NITFDESGetTRE( psDES, nOffset, szTREName, NULL, &nThisTRESize))
            {
                printf( " %6.6s(%d)", szTREName, nThisTRESize );
                if (strcmp(szTREName, "RPFDES") == 0)
                    nRPFDESOffset = nOffset + 11;
                nOffset += 11 + nThisTRESize;
            }
            printf( "\n" );

            if (bDisplayTRE)
            {
                char* pabyTREData = NULL;
                nOffset = 0;
                while (NITFDESGetTRE( psDES, nOffset, szTREName, &pabyTREData, &nThisTRESize))
                {
                    char* pszEscaped = CPLEscapeString( pabyTREData, nThisTRESize,
                                                        CPLES_BackslashQuotable );
                    printf( "  TRE '%6.6s' : %s\n", szTREName, pszEscaped);
                    CPLFree(pszEscaped);

                    nOffset += 11 + nThisTRESize;

                    NITFDESFreeTREData(pabyTREData);
                }
            }

            /* Report info from location table, if found. */
            if( !bHasFoundLocationTable && nRPFDESOffset >= 0 )
            {
                int i;
                int nLocCount = 0;
                NITFLocation* pasLocations;

                VSIFSeekL(psFile->fp, psSegInfo->nSegmentStart + nRPFDESOffset, SEEK_SET);
                pasLocations = NITFReadRPFLocationTable(psFile->fp, &nLocCount);
                if (pasLocations)
                {
                    printf( "  Location Table\n" );
                    for( i = 0; i < nLocCount; i++ )
                    {
                        printf( "    LocName=%s, LocId=%d, Offset=%u, Size=%u\n",
                                GetLocationNameFromId(pasLocations[i].nLocId),
                                pasLocations[i].nLocId,
                                pasLocations[i].nLocOffset,
                                pasLocations[i].nLocSize );
                    }

                    CPLFree(pasLocations);
                    printf( "\n" );
                }
            }

            DumpMetadata( "  DES Metadata:", "    ", psDES->papszMetadata );

            if ( bExtractSHP && CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE_USE") != NULL )
            {
                char szFilename[32];
                char szRadix[32];
                if (bExtractSHPInMem)
                    snprintf(szRadix, sizeof(szRadix), "/vsimem/nitf_segment_%d", iSegment + 1);
                else
                    snprintf(szRadix, sizeof(szRadix), "nitf_segment_%d", iSegment + 1);

                if (NITFDESExtractShapefile(psDES, szRadix))
                {
                    OGRDataSourceH hDS;
                    OGRRegisterAll();
                    snprintf(szFilename, sizeof(szFilename), "%s.SHP", szRadix);
                    hDS = OGROpen(szFilename, FALSE, NULL);
                    if (hDS)
                    {
                        int nGeom = 0;
                        OGRLayerH hLayer = OGR_DS_GetLayer(hDS, 0);
                        if (hLayer)
                        {
                            OGRFeatureH hFeat;
                            printf("\n");
                            while ( (hFeat = OGR_L_GetNextFeature(hLayer)) != NULL )
                            {
                                OGRGeometryH hGeom = OGR_F_GetGeometryRef(hFeat);
                                if (hGeom)
                                {
                                    char* pszWKT = NULL;
                                    OGR_G_ExportToWkt(hGeom, &pszWKT);
                                    if (pszWKT)
                                        printf("    Geometry %d : %s\n", nGeom ++, pszWKT);
                                    CPLFree(pszWKT);
                                }
                                OGR_F_Destroy(hFeat);
                            }
                        }
                        OGR_DS_Destroy(hDS);
                    }
                }

                if (bExtractSHPInMem)
                {
                    snprintf(szFilename, sizeof(szFilename), "%s.SHP", szRadix);
                    VSIUnlink(szFilename);
                    snprintf(szFilename, sizeof(szFilename), "%s.SHX", szRadix);
                    VSIUnlink(szFilename);
                    snprintf(szFilename, sizeof(szFilename), "%s.DBF", szRadix);
                    VSIUnlink(szFilename);
                }
            }
        }

/* -------------------------------------------------------------------- */
/*      Close.                                                          */
/* -------------------------------------------------------------------- */
        NITFClose( psFile );
    }

    CPLFinderClean();
    CPLCleanupTLS();
    VSICleanupFileManager();
    OGRCleanupAll();

    exit( 0 );
}
Esempio n. 22
0
int KmlRenderer::saveImage(imageObj *, FILE *fp, outputFormatObj *format)
{
  /* -------------------------------------------------------------------- */
  /*      Write out the document.                                         */
  /* -------------------------------------------------------------------- */

  int bufSize = 0;
  xmlChar *buf = NULL;
  msIOContext *context = NULL;
  int chunkSize = 4096;
#if defined(CPL_ZIP_API_OFFERED)
  int bZip = MS_FALSE;
#endif

  if( msIO_needBinaryStdout() == MS_FAILURE )
    return MS_FAILURE;

  xmlDocDumpFormatMemoryEnc(XmlDoc, &buf, &bufSize, "UTF-8", 1);

#if defined(USE_OGR)
  if (format && format->driver && strcasecmp(format->driver, "kmz") == 0) {
#if defined(CPL_ZIP_API_OFFERED)
    bZip = MS_TRUE;
#else
    msSetError( MS_MISCERR, "kmz format support unavailable, perhaps you need to upgrade to GDAL/OGR 1.8?",
                "KmlRenderer::saveImage()");
    xmlFree(buf);
    return MS_FAILURE;
#endif
  }

#if defined(CPL_ZIP_API_OFFERED)
  if (bZip) {
    VSILFILE *fpZip;
    int bytes_read;
    char buffer[1024];
    char *zip_filename =NULL;
    void *hZip=NULL;

    zip_filename = msTmpFile(NULL, NULL, "/vsimem/kmlzip/", "kmz" );
    hZip = CPLCreateZip( zip_filename, NULL );
    CPLCreateFileInZip( hZip, "mapserver.kml", NULL );
    for (int i=0; i<bufSize; i+=chunkSize) {
      int size = chunkSize;
      if (i + size > bufSize)
        size = bufSize - i;
      CPLWriteFileInZip( hZip,  buf+i, size);
    }
    CPLCloseFileInZip( hZip );
    CPLCloseZip( hZip );

    context = msIO_getHandler(fp);
    fpZip = VSIFOpenL( zip_filename, "r" );

    while( (bytes_read = VSIFReadL( buffer, 1, sizeof(buffer), fpZip )) > 0 ) {
      if (context)
        msIO_contextWrite(context, buffer, bytes_read);
      else
        msIO_fwrite( buffer, 1, bytes_read, fp );
    }
    VSIFCloseL( fpZip );
    msFree( zip_filename);
    xmlFree(buf);
    return(MS_SUCCESS);
  }
#endif

#endif

  context = msIO_getHandler(fp);


  for (int i=0; i<bufSize; i+=chunkSize) {
    int size = chunkSize;
    if (i + size > bufSize)
      size = bufSize - i;

    if (context)
      msIO_contextWrite(context, buf+i, size);
    else
      msIO_fwrite(buf+i, 1, size, fp);
  }

  xmlFree(buf);

  return(MS_SUCCESS);
}
Esempio n. 23
0
GDALDataset *CTGDataset::Open( GDALOpenInfo * poOpenInfo )

{
    int         i;

    if (!Identify(poOpenInfo))
        return NULL;

    CPLString osFilename(poOpenInfo->pszFilename);

    /*  GZipped grid_cell.gz files are common, so automagically open them */
    /*  if the /vsigzip/ has not been explicitly passed */
    const char* pszFilename = CPLGetFilename(poOpenInfo->pszFilename);
    if ((EQUAL(pszFilename, "grid_cell.gz") ||
         EQUAL(pszFilename, "grid_cell1.gz") ||
         EQUAL(pszFilename, "grid_cell2.gz")) &&
        !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
    {
        osFilename = "/vsigzip/";
        osFilename += poOpenInfo->pszFilename;
    }

    if (poOpenInfo->eAccess == GA_Update)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The CTG driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Find dataset characteristics                                    */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    char szHeader[HEADER_LINE_COUNT * 80+1];
    szHeader[HEADER_LINE_COUNT * 80] = 0;
    if (VSIFReadL(szHeader, 1, HEADER_LINE_COUNT * 80, fp) != HEADER_LINE_COUNT * 80)
    {
        VSIFCloseL(fp);
        return NULL;
    }

    for(i=HEADER_LINE_COUNT * 80 - 1;i>=0;i--)
    {
        if (szHeader[i] == ' ')
            szHeader[i] = 0;
        else
            break;
    }

    char szField[11];
    int nRows = atoi(ExtractField(szField, szHeader, 0, 10));
    int nCols = atoi(ExtractField(szField, szHeader, 20, 10));

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    CTGDataset         *poDS;

    poDS = new CTGDataset();
    poDS->fp = fp;
    fp = NULL;
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

    poDS->SetMetadataItem("TITLE", szHeader + 4 * 80);

    poDS->nCellSize = atoi(ExtractField(szField, szHeader, 35, 5));
    if (poDS->nCellSize <= 0 || poDS->nCellSize >= 10000)
    {
        delete poDS;
        return NULL;
    }
    poDS->nNWEasting = atoi(ExtractField(szField, szHeader + 3*80, 40, 10));
    poDS->nNWNorthing = atoi(ExtractField(szField, szHeader + 3*80, 50, 10));
    poDS->nUTMZone = atoi(ExtractField(szField, szHeader, 50, 5));
    if (poDS->nUTMZone <= 0 || poDS->nUTMZone > 60)
    {
        delete poDS;
        return NULL;
    }

    OGRSpatialReference oSRS;
    oSRS.importFromEPSG(32600 + poDS->nUTMZone);
    oSRS.exportToWkt(&poDS->pszProjection);

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

/* -------------------------------------------------------------------- */
/*      Read the imagery                                                */
/* -------------------------------------------------------------------- */
    GByte* pabyImage = (GByte*)VSICalloc(nCols * nRows, 6 * sizeof(int));
    if (pabyImage == NULL)
    {
        delete poDS;
        return NULL;
    }
    poDS->pabyImage = pabyImage;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 6;
    for( i = 0; i < poDS->nBands; i++ )
    {
        poDS->SetBand( i+1, new CTGRasterBand( poDS, i+1 ) );
        poDS->GetRasterBand(i+1)->SetDescription(apszBandDescription[i]);
    }

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

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

    return( poDS );
}
Esempio n. 24
0
RPFToc* RPFTOCReadFromBuffer(const char* pszFilename, VSILFILE* fp, const char* tocHeader)
{
    tocHeader += 1; /* skip endian */
    tocHeader += 2; /* skip header length */
    tocHeader += 12; /* skip file name : this should be A.TOC (padded) */
    tocHeader += 1; /* skip new  */
    tocHeader += 15; /* skip standard_num  */
    tocHeader += 8; /* skip standard_date  */
    tocHeader += 1; /* skip classification  */
    tocHeader += 2; /* skip country  */
    tocHeader += 2; /* skip release  */

    unsigned int locationSectionPhysicalLocation;
    memcpy(&locationSectionPhysicalLocation, tocHeader, sizeof(unsigned int));
    CPL_MSBPTR32(&locationSectionPhysicalLocation);

    if( VSIFSeekL( fp, locationSectionPhysicalLocation, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to locationSectionPhysicalLocation at offset %d.",
                   locationSectionPhysicalLocation );
        return NULL;
    }

    int nSections;
    NITFLocation* pasLocations = NITFReadRPFLocationTable(fp, &nSections);

    unsigned int boundaryRectangleSectionSubHeaderPhysIndex = 0;
    unsigned int boundaryRectangleTablePhysIndex = 0;
    unsigned int frameFileIndexSectionSubHeaderPhysIndex = 0;
    unsigned int frameFileIndexSubsectionPhysIndex = 0;

    for( int i = 0; i < nSections; i++ )
    {
        if (pasLocations[i].nLocId == LID_BoundaryRectangleSectionSubheader)
        {
            boundaryRectangleSectionSubHeaderPhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_BoundaryRectangleTable)
        {
            boundaryRectangleTablePhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_FrameFileIndexSectionSubHeader)
        {
            frameFileIndexSectionSubHeaderPhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_FrameFileIndexSubsection)
        {
            frameFileIndexSubsectionPhysIndex = pasLocations[i].nLocOffset;
        }
    }

    CPLFree(pasLocations);

    if (boundaryRectangleSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_BoundaryRectangleSectionSubheader." );
        return NULL;
    }
    if (boundaryRectangleTablePhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_BoundaryRectangleTable." );
        return NULL;
    }
    if (frameFileIndexSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_FrameFileIndexSectionSubHeader." );
        return NULL;
    }
    if (frameFileIndexSubsectionPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_FrameFileIndexSubsection." );
        return NULL;
    }

    if( VSIFSeekL( fp, boundaryRectangleSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to boundaryRectangleSectionSubHeaderPhysIndex at offset %d.",
                   boundaryRectangleSectionSubHeaderPhysIndex );
        return NULL;
    }

    unsigned int boundaryRectangleTableOffset;
    bool bOK = VSIFReadL( &boundaryRectangleTableOffset, sizeof(boundaryRectangleTableOffset), 1, fp) == 1;
    CPL_MSBPTR32( &boundaryRectangleTableOffset );

    unsigned short boundaryRectangleCount;
    bOK &= VSIFReadL( &boundaryRectangleCount, sizeof(boundaryRectangleCount), 1, fp) == 1;
    CPL_MSBPTR16( &boundaryRectangleCount );

    if( !bOK || VSIFSeekL( fp, boundaryRectangleTablePhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to boundaryRectangleTablePhysIndex at offset %d.",
                   boundaryRectangleTablePhysIndex );
        return NULL;
    }

    RPFToc* toc = reinterpret_cast<RPFToc *>( CPLMalloc( sizeof( RPFToc ) ) );
    toc->nEntries = boundaryRectangleCount;
    toc->entries = reinterpret_cast<RPFTocEntry *>(
        CPLMalloc( boundaryRectangleCount * sizeof(RPFTocEntry) ) );
    memset(toc->entries, 0, boundaryRectangleCount * sizeof(RPFTocEntry));

    for( int i = 0; i < toc->nEntries; i++ )
    {
        toc->entries[i].isOverviewOrLegend = 0;

        bOK &= VSIFReadL( toc->entries[i].type, 1, 5, fp) == 5;
        toc->entries[i].type[5] = 0;
        RPFTOCTrim(toc->entries[i].type);

        bOK &= VSIFReadL( toc->entries[i].compression, 1, 5, fp) == 5;
        toc->entries[i].compression[5] = 0;
        RPFTOCTrim(toc->entries[i].compression);

        bOK &= VSIFReadL( toc->entries[i].scale, 1, 12, fp) == 12;
        toc->entries[i].scale[12] = 0;
        RPFTOCTrim(toc->entries[i].scale);
        if (toc->entries[i].scale[0] == '1' &&
            toc->entries[i].scale[1] == ':')
        {
            memmove(toc->entries[i].scale,
                    toc->entries[i].scale+2,
                    strlen(toc->entries[i].scale+2)+1);
        }

        bOK &= VSIFReadL( toc->entries[i].zone, 1, 1, fp) == 1;
        toc->entries[i].zone[1] = 0;
        RPFTOCTrim(toc->entries[i].zone);

        bOK &= VSIFReadL( toc->entries[i].producer, 1, 5, fp) == 5;
        toc->entries[i].producer[5] = 0;
        RPFTOCTrim(toc->entries[i].producer);

        bOK &= VSIFReadL( &toc->entries[i].nwLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].nwLat);

        bOK &= VSIFReadL( &toc->entries[i].nwLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].nwLong);

        bOK &= VSIFReadL( &toc->entries[i].swLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].swLat);

        bOK &= VSIFReadL( &toc->entries[i].swLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].swLong);

        bOK &= VSIFReadL( &toc->entries[i].neLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].neLat);

        bOK &= VSIFReadL( &toc->entries[i].neLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].neLong);

        bOK &= VSIFReadL( &toc->entries[i].seLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].seLat);

        bOK &= VSIFReadL( &toc->entries[i].seLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].seLong);

        bOK &= VSIFReadL( &toc->entries[i].vertResolution, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].vertResolution);

        bOK &= VSIFReadL( &toc->entries[i].horizResolution, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].horizResolution);

        bOK &= VSIFReadL( &toc->entries[i].vertInterval, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].vertInterval);

        bOK &= VSIFReadL( &toc->entries[i].horizInterval, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].horizInterval);

        bOK &= VSIFReadL( &toc->entries[i].nVertFrames, sizeof(int), 1, fp) == 1;
        CPL_MSBPTR32( &toc->entries[i].nVertFrames );

        bOK &= VSIFReadL( &toc->entries[i].nHorizFrames, sizeof(int), 1, fp) == 1;
        CPL_MSBPTR32( &toc->entries[i].nHorizFrames );

        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return NULL;
        }

        if( toc->entries[i].nHorizFrames == 0 ||
            toc->entries[i].nVertFrames == 0 ||
            toc->entries[i].nHorizFrames > INT_MAX / toc->entries[i].nVertFrames )
        {
            toc->entries[i].frameEntries = NULL;
        }
        else
        {
            toc->entries[i].frameEntries = reinterpret_cast<RPFTocFrameEntry*>(
                VSI_CALLOC_VERBOSE( toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames,
                                    sizeof(RPFTocFrameEntry) ) );
        }
        if (toc->entries[i].frameEntries == NULL)
        {
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return NULL;
        }

        CPLDebug("RPFTOC", "[%d] type=%s, compression=%s, scale=%s, zone=%s, producer=%s, nVertFrames=%d, nHorizFrames=%d",
                 i, toc->entries[i].type, toc->entries[i].compression, toc->entries[i].scale,
                 toc->entries[i].zone, toc->entries[i].producer, toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames);
    }

    if( VSIFSeekL( fp, frameFileIndexSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to frameFileIndexSectionSubHeaderPhysIndex at offset %d.",
                   frameFileIndexSectionSubHeaderPhysIndex );
        RPFTOCFree(toc);
        return NULL;
    }

    /* Skip 1 byte security classification */
    bOK &= VSIFSeekL( fp, 1, SEEK_CUR ) == 0;

    unsigned int frameIndexTableOffset;
    bOK &= VSIFReadL( &frameIndexTableOffset, sizeof(frameIndexTableOffset), 1, fp) == 1;
    CPL_MSBPTR32( &frameIndexTableOffset );

    unsigned int nFrameFileIndexRecords;
    bOK &= VSIFReadL( &nFrameFileIndexRecords, sizeof(nFrameFileIndexRecords), 1, fp) == 1;
    CPL_MSBPTR32( &nFrameFileIndexRecords );

    unsigned short nFrameFilePathnameRecords;
    bOK &= VSIFReadL( &nFrameFilePathnameRecords, sizeof(nFrameFilePathnameRecords), 1, fp) == 1;
    CPL_MSBPTR16( &nFrameFilePathnameRecords );

    unsigned short frameFileIndexRecordLength;
    bOK &= VSIFReadL( &frameFileIndexRecordLength, sizeof(frameFileIndexRecordLength), 1, fp) == 1;
    CPL_MSBPTR16( &frameFileIndexRecordLength );

    if( !bOK )
    {
        CPLError(CE_Failure, CPLE_FileIO, "I/O error");
        RPFTOCFree(toc);
        return NULL;
    }

    int newBoundaryId = 0;

    for( int i = 0; i < static_cast<int>( nFrameFileIndexRecords ); i++ )
    {
        if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                    "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i);
            RPFTOCFree(toc);
            return NULL;
        }

        unsigned short boundaryId;
        if( VSIFReadL( &boundaryId, sizeof(boundaryId), 1, fp) != 1 )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return NULL;
        }
        CPL_MSBPTR16( &boundaryId );

        if (i == 0 && boundaryId == 0)
            newBoundaryId = 1;
        if (newBoundaryId == 0)
            boundaryId--;

        if (boundaryId >= toc->nEntries)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                    "Invalid TOC file. Bad boundary id (%d) for frame file index %d.",
                     boundaryId, i);
            RPFTOCFree(toc);
            return NULL;
        }

        RPFTocEntry* entry = &toc->entries[boundaryId];
        entry->boundaryId = boundaryId;

        unsigned short frameRow;
        bOK &= VSIFReadL( &frameRow, sizeof(frameRow), 1, fp) == 1;
        CPL_MSBPTR16( &frameRow );

        unsigned short frameCol;
        bOK &= VSIFReadL( &frameCol, sizeof(frameCol), 1, fp) == 1;
        CPL_MSBPTR16( &frameCol );
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return NULL;
        }

        if (newBoundaryId == 0)
        {
            frameRow--;
            frameCol--;
        }
        else
        {
            /* Trick so that frames are numbered north to south */
            frameRow = (unsigned short)((entry->nVertFrames-1) - frameRow);
        }

        if (frameRow >= entry->nVertFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                        "Invalid TOC file. Bad row num (%d) for frame file index %d.",
                        frameRow, i);
            RPFTOCFree(toc);
            return NULL;
        }

        if (frameCol >= entry->nHorizFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                        "Invalid TOC file. Bad col num (%d) for frame file index %d.",
                        frameCol, i);
            RPFTOCFree(toc);
            return NULL;
        }

        RPFTocFrameEntry* frameEntry
            = &entry->frameEntries[frameRow * entry->nHorizFrames + frameCol ];
        frameEntry->frameRow = frameRow;
        frameEntry->frameCol = frameCol;

        if (frameEntry->exists)
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Frame entry(%d,%d) for frame file index %d was already found.",
                      frameRow, frameCol, i);
            CPLFree(frameEntry->directory);
            frameEntry->directory = NULL;
            CPLFree(frameEntry->fullFilePath);
            frameEntry->fullFilePath = NULL;
            frameEntry->exists = 0;
        }

        unsigned int offsetFrameFilePathName;
        bOK &= VSIFReadL( &offsetFrameFilePathName, sizeof(offsetFrameFilePathName), 1, fp) == 1;
        CPL_MSBPTR32( &offsetFrameFilePathName );

        bOK &= VSIFReadL( frameEntry->filename, 1, 12, fp) == 12;
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return NULL;
        }
        frameEntry->filename[12] = '\0';

        /* Check if the filename is an overview or legend */
        for( int j = 0; j < 12; j++ )
        {
            if (strcmp(&(frameEntry->filename[j]),".OVR") == 0 ||
                strcmp(&(frameEntry->filename[j]),".ovr") == 0 ||
                strcmp(&(frameEntry->filename[j]),".LGD") == 0 ||
                strcmp(&(frameEntry->filename[j]),".lgd") == 0)
            {
                entry->isOverviewOrLegend = TRUE;
                break;
            }
        }

        /* Extract series code */
        if (entry->seriesAbbreviation == NULL)
        {
            const NITFSeries* series = NITFGetSeriesInfo(frameEntry->filename);
            if (series)
            {
                entry->seriesAbbreviation = series->abbreviation;
                entry->seriesName = series->name;
            }
        }

        /* Get file geo reference */
        bOK &= VSIFReadL( frameEntry->georef, 1, 6, fp) == 6;
        frameEntry->georef[6] = '\0';

        /* Go to start of pathname record */
        /* New path_off offset from start of frame file index section of TOC?? */
        /* Add pathoffset wrt frame file index table subsection (loc[3]) */
        if( !bOK || VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Invalid TOC file. Unable to seek to "
                      "frameFileIndexSubsectionPhysIndex + "
                      "offsetFrameFilePathName(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName);
            RPFTOCFree(toc);
            return NULL;
        }

        unsigned short pathLength;
        bOK &= VSIFReadL( &pathLength, sizeof(pathLength), 1, fp) == 1;
        CPL_MSBPTR16( &pathLength );

        /* if nFrameFileIndexRecords == 65535 and pathLength == 65535 for each record,
           this leads to 4 GB allocation... Protect against this case */
        if (!bOK || pathLength > 256)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Path length is big : %d. Probably corrupted TOC file.",
                      static_cast<int>( pathLength ) );
            RPFTOCFree(toc);
            return NULL;
        }

        frameEntry->directory = reinterpret_cast<char *>( CPLMalloc(pathLength+1) );
        bOK &= VSIFReadL( frameEntry->directory, 1, pathLength, fp) == pathLength;
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return NULL;
        }
        frameEntry->directory[pathLength] = 0;
        if (pathLength > 0 && frameEntry->directory[pathLength-1] == '/')
            frameEntry->directory[pathLength-1] = 0;

        if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == '/')
        {
            memmove(frameEntry->directory, frameEntry->directory+2, strlen(frameEntry->directory+2)+1);

            // Some A.TOC have subdirectory names like ".//X/" ... (#5979)
            // Check if it was not intended to be "./X/" instead.
            VSIStatBufL sStatBuf;
            if( frameEntry->directory[0] == '/' &&
                VSIStatL(CPLFormFilename(CPLGetDirname(pszFilename), frameEntry->directory+1, NULL), &sStatBuf) == 0 &&
                VSI_ISDIR(sStatBuf.st_mode) )
            {
                memmove(frameEntry->directory, frameEntry->directory+1, strlen(frameEntry->directory+1)+1);
            }
        }

        {
            char* baseDir = CPLStrdup(CPLGetDirname(pszFilename));
            VSIStatBufL sStatBuf;
            char* subdir;
            if (CPLIsFilenameRelative(frameEntry->directory) == FALSE)
                subdir = CPLStrdup(frameEntry->directory);
            else if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == 0)
                subdir = CPLStrdup(baseDir);
            else
                subdir = CPLStrdup(CPLFormFilename(baseDir, frameEntry->directory, NULL));
#if !defined(_WIN32) && !defined(_WIN32_CE)
            if( VSIStatL( subdir, &sStatBuf ) != 0 && strlen(subdir) > strlen(baseDir) && subdir[strlen(baseDir)] != 0)
            {
                char* c = subdir + strlen(baseDir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
            }
#endif
            frameEntry->fullFilePath = CPLStrdup(CPLFormFilename(
                    subdir,
                    frameEntry->filename, NULL));
            if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
            {
#if !defined(_WIN32) && !defined(_WIN32_CE)
                char* c = frameEntry->fullFilePath + strlen(subdir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
                if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
#endif
                {
                    frameEntry->fileExists = 0;
                    CPLError( CE_Warning, CPLE_AppDefined,
                        "File %s does not exist.", frameEntry->fullFilePath );
                }
#if !defined(_WIN32) && !defined(_WIN32_CE)
                else
                {
                    frameEntry->fileExists = 1;
                }
#endif
            }
            else
            {
                frameEntry->fileExists = 1;
            }
            CPLFree(subdir);
            CPLFree(baseDir);
        }

        CPLDebug("RPFTOC", "Entry %d : %s,%s (%d, %d)", boundaryId, frameEntry->directory, frameEntry->filename, frameRow, frameCol);

        frameEntry->exists = 1;
    }

    return toc;
}
Esempio n. 25
0
CPLErr E00GRIDRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                      void * pImage )

{
    E00GRIDDataset *poGDS = (E00GRIDDataset *) poDS;

    char szVal[E00_FLOAT_SIZE+1];
    szVal[E00_FLOAT_SIZE] = 0;

    int i;
    float* pafImage = (float*)pImage;
    int* panImage = (int*)pImage;
    const float fNoData = (const float)poGDS->dfNoData;

    /* A new data line begins on a new text line. So if the xsize */
    /* is not a multiple of VALS_PER_LINE, there are padding values */
    /* that must be ignored */
    const int nRoundedBlockXSize = ((nBlockXSize + VALS_PER_LINE - 1) /
                                            VALS_PER_LINE) * VALS_PER_LINE;

    if (poGDS->e00ReadPtr)
    {
        if (poGDS->nLastYOff < 0)
        {
            E00ReadRewind(poGDS->e00ReadPtr);
            for(i=0;i<6;i++)
                E00ReadNextLine(poGDS->e00ReadPtr);
        }

        if (nBlockYOff == poGDS->nLastYOff + 1)
        {
        }
        else if (nBlockYOff <= poGDS->nMaxYOffset)
        {
            //CPLDebug("E00GRID", "Skip to %d from %d", nBlockYOff, poGDS->nLastYOff);
            VSIFSeekL(poGDS->fp, poGDS->panOffsets[nBlockYOff], SEEK_SET);
            poGDS->nPosBeforeReadLine = poGDS->panOffsets[nBlockYOff];
            poGDS->e00ReadPtr->iInBufPtr = 0;
            poGDS->e00ReadPtr->szInBuf[0] = '\0';
        }
        else if (nBlockYOff > poGDS->nLastYOff + 1)
        {
            //CPLDebug("E00GRID", "Forward skip to %d from %d", nBlockYOff, poGDS->nLastYOff);
            for(i=poGDS->nLastYOff + 1; i < nBlockYOff;i++)
                IReadBlock(0, i, pImage);
        }

        if (nBlockYOff > poGDS->nMaxYOffset)
        {
            poGDS->panOffsets[nBlockYOff] = poGDS->nPosBeforeReadLine +
                                            poGDS->e00ReadPtr->iInBufPtr;
            poGDS->nMaxYOffset = nBlockYOff;
        }

        const char* pszLine = NULL;
        for(i=0;i<nBlockXSize;i++)
        {
            if ((i % VALS_PER_LINE) == 0)
            {
                pszLine = E00ReadNextLine(poGDS->e00ReadPtr);
                if (pszLine == NULL || strlen(pszLine) < 5 * E00_FLOAT_SIZE)
                    return CE_Failure;
            }
            if (eDataType == GDT_Float32)
            {
                pafImage[i] = (float) atof(pszLine + (i%VALS_PER_LINE) * E00_FLOAT_SIZE);
                /* Workaround single vs double precision problems */
                if (fNoData != 0 && fabs((pafImage[i] - fNoData)/fNoData) < 1e-6)
                    pafImage[i] = fNoData;
            }
            else
            {
                panImage[i] = atoi(pszLine + (i%VALS_PER_LINE) * E00_FLOAT_SIZE);
            }
        }

        poGDS->nLastYOff = nBlockYOff;

        return CE_None;
    }

    vsi_l_offset nValsToSkip = (vsi_l_offset)nBlockYOff * nRoundedBlockXSize;
    vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE;
    int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + poGDS->nBytesEOL;
    vsi_l_offset nPos = poGDS->nDataStart + nLinesToSkip * nBytesPerLine;
    VSIFSeekL(poGDS->fp, nPos, SEEK_SET);

    for(i=0;i<nBlockXSize;i++)
    {
        if (VSIFReadL(szVal, E00_FLOAT_SIZE, 1, poGDS->fp) != 1)
            return CE_Failure;

        if (eDataType == GDT_Float32)
        {
            pafImage[i] = (float) atof(szVal);
            /* Workaround single vs double precision problems */
            if (fNoData != 0 && fabs((pafImage[i] - fNoData)/fNoData) < 1e-6)
                pafImage[i] = fNoData;
        }
        else
        {
            panImage[i] = atoi(szVal);
        }

        if (((i+1) % VALS_PER_LINE) == 0)
            VSIFReadL(szVal, poGDS->nBytesEOL, 1, poGDS->fp);
    }

    return CE_None;
}
Esempio n. 26
0
GDALDataset *GSBGDataset::Open( GDALOpenInfo * poOpenInfo )

{
    /* Check for signature */
    if( poOpenInfo->nHeaderBytes < 4
	|| !EQUALN((const char *) poOpenInfo->pabyHeader,"DSBB",4) )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    GSBGDataset	*poDS = new GSBGDataset();

/* -------------------------------------------------------------------- */
/*      Open file with large file API.                                  */
/* -------------------------------------------------------------------- */
    poDS->eAccess = poOpenInfo->eAccess;
    if( poOpenInfo->eAccess == GA_ReadOnly )
    	poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
    	poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );

    if( poDS->fp == NULL )
    {
	delete poDS;
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "VSIFOpenL(%s) failed unexpectedly.", 
                  poOpenInfo->pszFilename );
        return NULL;
    }
 
/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    if( VSIFSeekL( poDS->fp, 4, SEEK_SET ) != 0 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of grid file header.\n" );
	return NULL;
    }

    /* Parse number of X axis grid rows */
    GInt16 nTemp;
    if( VSIFReadL( (void *)&nTemp, 2, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO, "Unable to read raster X size.\n" );
	return NULL;
    }
    poDS->nRasterXSize = CPL_LSBWORD16( nTemp );

    if( VSIFReadL( (void *)&nTemp, 2, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO, "Unable to read raster Y size.\n" );
	return NULL;
    }
    poDS->nRasterYSize = CPL_LSBWORD16( nTemp );

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

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    GSBGRasterBand *poBand = new GSBGRasterBand( poDS, 1 );

    double dfTemp;
    if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to read minimum X value.\n" );
	return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMinX = dfTemp;

    if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to read maximum X value.\n" );
	return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMaxX = dfTemp;

    if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to read minimum Y value.\n" );
	return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMinY = dfTemp;

    if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to read maximum Y value.\n" );
	return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMaxY = dfTemp;

    if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to read minimum Z value.\n" );
	return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMinZ = dfTemp;

    if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 )
    {
	delete poDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to read maximum Z value.\n" );
	return NULL;
    }
    CPL_LSBPTR64( &dfTemp );
    poBand->dfMaxZ = dfTemp;

    poDS->SetBand( 1, poBand );

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

    return poDS;
}
Esempio n. 27
0
bool TerragenDataset::read_next_tag(char* szTag)
{
    return 1 == VSIFReadL(szTag, 4, 1, m_fp);
}
Esempio n. 28
0
int OGRARCGENDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        return FALSE;
    }

    pszName = CPLStrdup( pszFilename );

// -------------------------------------------------------------------- 
//      Does this appear to be a Arc/Info generate file?
// --------------------------------------------------------------------

    VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
    if (fp == NULL)
        return FALSE;

    /* Check that the first line is compatible with a generate file */
    /* and in particular contain >= 32 && <= 127 bytes */
    char szFirstLine[256+1];
    int nRet = VSIFReadL(szFirstLine, 1, 256, fp);
    szFirstLine[nRet] = '\0';

    int i;
    int bFoundEOL = FALSE;
    for(i=0;szFirstLine[i] != '\0';i++)
    {
        if (szFirstLine[i] == '\n' || szFirstLine[i] == '\r')
        {
            bFoundEOL = TRUE;
            szFirstLine[i] = '\0';
            break;
        }
        if (szFirstLine[i] < 32)
        {
            VSIFCloseL(fp);
            return FALSE;
        }
    }

    if (!bFoundEOL)
    {
        VSIFCloseL(fp);
        return FALSE;
    }

    char** papszTokens = CSLTokenizeString2( szFirstLine, " ,", 0 );
    int nTokens = CSLCount(papszTokens);
    if (nTokens != 1 && nTokens != 3 && nTokens != 4)
    {
        VSIFCloseL(fp);
        CSLDestroy(papszTokens);
        return FALSE;
    }
    for(int i=0;i<nTokens;i++)
    {
        if( CPLGetValueType(papszTokens[i]) == CPL_VALUE_STRING )
        {
            VSIFCloseL(fp);
            CSLDestroy(papszTokens);
            return FALSE;
        }
    }
    CSLDestroy(papszTokens);

    /* Go to end of file, and count the number of END keywords */
    /* If there's 1, it's a point layer */
    /* If there's 2, it's a linestring or polygon layer */
    VSIFSeekL( fp, 0, SEEK_END );
    vsi_l_offset nSize = VSIFTellL(fp);
    if (nSize < 10)
    {
        VSIFCloseL(fp);
        return FALSE;
    }
    char szBuffer[10+1];
    VSIFSeekL( fp, nSize - 10, SEEK_SET );
    VSIFReadL( szBuffer, 1, 10, fp );
    szBuffer[10] = '\0';

    VSIFSeekL( fp, 0, SEEK_SET );

    OGRwkbGeometryType eType;
    const char* szPtr = szBuffer;
    const char* szEnd = strstr(szPtr, "END");
    if (szEnd == NULL) szEnd = strstr(szPtr, "end");
    if (szEnd == NULL)
    {
        VSIFCloseL(fp);
        return FALSE;
    }
    szPtr = szEnd + 3;
    szEnd = strstr(szPtr, "END");
    if (szEnd == NULL) szEnd = strstr(szPtr, "end");
    if (szEnd == NULL)
    {
        const char* pszLine = CPLReadLine2L(fp,256,NULL);
        if (pszLine == NULL)
        {
            VSIFCloseL(fp);
            return FALSE;
        }
        char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 );
        int nTokens = CSLCount(papszTokens);
        CSLDestroy(papszTokens);

        if (nTokens == 3)
            eType = wkbPoint;
        else if (nTokens == 4)
            eType = wkbPoint25D;
        else
        {
            VSIFCloseL(fp);
            return FALSE;
        }
    }
    else
    {
        int nLineNumber = 0;
        eType = wkbUnknown;
        CPLString osFirstX, osFirstY;
        CPLString osLastX, osLastY;
        int bIs3D = FALSE;
        const char* pszLine;
        while((pszLine = CPLReadLine2L(fp,256,NULL)) != NULL)
        {
            nLineNumber ++;
            if (nLineNumber == 2)
            {
                char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 );
                int nTokens = CSLCount(papszTokens);
                if (nTokens == 2 || nTokens == 3)
                {
                    if (nTokens == 3)
                        bIs3D = TRUE;
                    osFirstX = papszTokens[0];
                    osFirstY = papszTokens[1];
                }
                CSLDestroy(papszTokens);
                if (nTokens != 2 && nTokens != 3)
                    break;
            }
            else if (nLineNumber > 2)
            {
                if (EQUAL(pszLine, "END"))
                {
                    if (osFirstX.compare(osLastX) == 0 &&
                        osFirstY.compare(osLastY) == 0)
                        eType = (bIs3D) ? wkbPolygon25D : wkbPolygon;
                    else
                        eType = (bIs3D) ? wkbLineString25D : wkbLineString;
                    break;
                }

                char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 );
                int nTokens = CSLCount(papszTokens);
                if (nTokens == 2 || nTokens == 3)
                {
                    osLastX = papszTokens[0];
                    osLastY = papszTokens[1];
                }
                CSLDestroy(papszTokens);
                if (nTokens != 2 && nTokens != 3)
                    break;
            }
        }
        if (eType == wkbUnknown)
        {
            VSIFCloseL(fp);
            return FALSE;
        }
    }

    VSIFSeekL( fp, 0, SEEK_SET );

    nLayers = 1;
    papoLayers = (OGRLayer**) CPLMalloc(sizeof(OGRLayer*));
    papoLayers[0] = new OGRARCGENLayer(pszName, fp, eType);

    return TRUE;
}
Esempio n. 29
0
GDALDataset *OZIDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if (!Identify(poOpenInfo))
        return NULL;

    GByte abyHeader[14];
    CPLString osImgFilename = poOpenInfo->pszFilename;
    int bIsMap = FALSE;
    if (EQUALN((const char*)poOpenInfo->pabyHeader,
        "OziExplorer Map Data File Version ", 34) )
    {
        char** papszLines = CSLLoad2( poOpenInfo->pszFilename, 1000, 200, NULL );
        if ( !papszLines || CSLCount(papszLines) < 5)
        {
            CSLDestroy(papszLines);
            return FALSE;
        }

        bIsMap = TRUE;

        osImgFilename = papszLines[2];
        VSIStatBufL sStat;
        if (VSIStatL(osImgFilename, &sStat) != 0)
        {
            if (CPLIsFilenameRelative(osImgFilename))
            {
                CPLString osPath = CPLGetPath(poOpenInfo->pszFilename);
                osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL);
            }
            else
            {
                CPLString osPath = CPLGetPath(poOpenInfo->pszFilename);
                osImgFilename = CPLGetFilename(osImgFilename);
                osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL);
            }
        }

        CSLDestroy(papszLines);

        GDALOpenInfo oOpenInfo(osImgFilename, GA_ReadOnly);
        if (!Identify(&oOpenInfo))
            return NULL;
        memcpy(abyHeader, oOpenInfo.pabyHeader, 14);
    }
    else
        memcpy(abyHeader, poOpenInfo->pabyHeader, 14);

    int bOzi3 = (abyHeader[0] == 0x80 &&
                 abyHeader[1] == 0x77);

    VSILFILE* fp = VSIFOpenL(osImgFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    OZIDataset* poDS = new OZIDataset();
    poDS->fp = fp;

    if (bIsMap)
    {
        poDS->bReadMapFileSuccess =
            GDALLoadOziMapFile( poOpenInfo->pszFilename,
                                poDS->adfGeoTransform,
                                &poDS->pszWKT,
                                &poDS->nGCPCount,
                                &poDS->pasGCPs );
    }

    GByte nRandomNumber = 0;
    GByte nKeyInit = 0;
    if (bOzi3)
    {
        VSIFSeekL(fp, 14, SEEK_SET);
        VSIFReadL(&nRandomNumber, 1, 1, fp);
        //printf("nRandomNumber = %d\n", nRandomNumber);
        if (nRandomNumber < 0x94)
        {
            delete poDS;
            return NULL;
        }
        VSIFSeekL(fp, 0x93, SEEK_CUR);
        VSIFReadL(&nKeyInit, 1, 1, fp);

        VSIFSeekL(fp, 0, SEEK_SET);
        VSIFReadL(abyHeader, 1, 14, fp);
        OZIDecrypt(abyHeader, 14, nKeyInit);
        if (!(abyHeader[6] == 0x40 &&
           abyHeader[7] == 0x00 &&
           abyHeader[8] == 0x01 &&
           abyHeader[9] == 0x00 &&
           abyHeader[10] == 0x36 &&
           abyHeader[11] == 0x04 &&
           abyHeader[12] == 0x00 &&
           abyHeader[13] == 0x00))
        {
            delete poDS;
            return NULL;
        }

        VSIFSeekL(fp, 14 + 1 + nRandomNumber, SEEK_SET);
        int nMagic = ReadInt(fp, bOzi3, nKeyInit);
        CPLDebug("OZI", "OZI version code : 0x%08X", nMagic);

        poDS->bOzi3 = bOzi3;
    }
    else
    {
        VSIFSeekL(fp, 14, SEEK_SET);
    }

    GByte abyHeader2[40], abyHeader2_Backup[40];
    VSIFReadL(abyHeader2, 40, 1, fp);
    memcpy(abyHeader2_Backup, abyHeader2, 40);

    /* There's apparently a relationship between the nMagic number */
    /* and the nKeyInit, but I'm too lazy to add switch/cases that might */
    /* be not exhaustive, so let's try the 'brute force' attack !!! */
    /* It is much so funny to be able to run one in a few microseconds :-) */
    for(nKeyInit = 0; nKeyInit < 256; nKeyInit ++)
    {
        GByte* pabyHeader2 = abyHeader2;
        if (bOzi3)
            OZIDecrypt(abyHeader2, 40, nKeyInit);

        int nHeaderSize = ReadInt(&pabyHeader2); /* should be 40 */
        poDS->nRasterXSize = ReadInt(&pabyHeader2);
        poDS->nRasterYSize = ReadInt(&pabyHeader2);
        int nDepth = ReadShort(&pabyHeader2); /* should be 1 */
        int nBPP = ReadShort(&pabyHeader2); /* should be 8 */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* pixel number (height * width) : unused */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* ?? 0x100 */
        ReadInt(&pabyHeader2); /* ?? 0x100 */

        if (nHeaderSize != 40 || nDepth != 1 || nBPP != 8)
        {
            if (bOzi3)
            {
                if (nKeyInit != 255)
                {
                    memcpy(abyHeader2, abyHeader2_Backup,40);
                    continue;
                }
                else
                {
                    CPLDebug("OZI", "Cannot decypher 2nd header. Sorry...");
                    delete poDS;
                    return NULL;
                }
            }
            else
            {
                CPLDebug("OZI", "nHeaderSize = %d, nDepth = %d, nBPP = %d",
                        nHeaderSize, nDepth, nBPP);
                delete poDS;
                return NULL;
            }
        }
        else
            break;
    }
    poDS->nKeyInit = nKeyInit;

    int nSeparator = ReadInt(fp);
    if (!bOzi3 && nSeparator != 0x77777777)
    {
        CPLDebug("OZI", "didn't get end of header2 marker");
        delete poDS;
        return NULL;
    }

    poDS->nZoomLevelCount = ReadShort(fp);
    //CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount);
    if (poDS->nZoomLevelCount < 0 || poDS->nZoomLevelCount >= 256)
    {
        CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount);
        delete poDS;
        return NULL;
    }

    /* Skip array of zoom level percentage. We don't need it for GDAL */
    VSIFSeekL(fp, sizeof(float) * poDS->nZoomLevelCount, SEEK_CUR);

    nSeparator = ReadInt(fp);
    if (!bOzi3 && nSeparator != 0x77777777)
    {
        /* Some files have 8 extra bytes before the marker. I'm not sure */
        /* what they are used for. So just skeep them and hope that */
        /* we'll find the marker */
        nSeparator = ReadInt(fp);
        nSeparator = ReadInt(fp);
        if (nSeparator != 0x77777777)
        {
            CPLDebug("OZI", "didn't get end of zoom levels marker");
            delete poDS;
            return NULL;
        }
    }

    VSIFSeekL(fp, 0, SEEK_END);
    vsi_l_offset nFileSize = VSIFTellL(fp);
    poDS->nFileSize = nFileSize;
    VSIFSeekL(fp, nFileSize - 4, SEEK_SET);
    int nZoomLevelTableOffset = ReadInt(fp, bOzi3, nKeyInit);
    if (nZoomLevelTableOffset < 0 ||
        (vsi_l_offset)nZoomLevelTableOffset >= nFileSize)
    {
        CPLDebug("OZI", "nZoomLevelTableOffset = %d",
                 nZoomLevelTableOffset);
        delete poDS;
        return NULL;
    }

    VSIFSeekL(fp, nZoomLevelTableOffset, SEEK_SET);

    poDS->panZoomLevelOffsets =
        (int*)CPLMalloc(sizeof(int) * poDS->nZoomLevelCount);
    int i;
    for(i=0;i<poDS->nZoomLevelCount;i++)
    {
        poDS->panZoomLevelOffsets[i] = ReadInt(fp, bOzi3, nKeyInit);
        if (poDS->panZoomLevelOffsets[i] < 0 ||
            (vsi_l_offset)poDS->panZoomLevelOffsets[i] >= nFileSize)
        {
            CPLDebug("OZI", "panZoomLevelOffsets[%d] = %d",
                     i, poDS->panZoomLevelOffsets[i]);
            delete poDS;
            return NULL;
        }
    }

    poDS->papoBands =
        (OZIRasterBand**)CPLCalloc(sizeof(OZIRasterBand*), poDS->nZoomLevelCount);

    for(i=0;i<poDS->nZoomLevelCount;i++)
    {
        VSIFSeekL(fp, poDS->panZoomLevelOffsets[i], SEEK_SET);
        int nW = ReadInt(fp, bOzi3, nKeyInit);
        int nH = ReadInt(fp, bOzi3, nKeyInit);
        short nTileX = ReadShort(fp, bOzi3, nKeyInit);
        short nTileY = ReadShort(fp, bOzi3, nKeyInit);
        if (i == 0 && (nW != poDS->nRasterXSize || nH != poDS->nRasterYSize))
        {
            CPLDebug("OZI", "zoom[%d] inconsistant dimensions for zoom level 0 : nW=%d, nH=%d, nTileX=%d, nTileY=%d, nRasterXSize=%d, nRasterYSize=%d",
                     i, nW, nH, nTileX, nTileY, poDS->nRasterXSize, poDS->nRasterYSize);
            delete poDS;
            return NULL;
        }
        /* Note (#3895): some files such as world.ozf2 provided with OziExplorer */
        /* expose nTileY=33, but have nH=2048, so only require 32 tiles in vertical dimension. */
        /* So there's apparently one extra and useless tile that will be ignored */
        /* without causing apparent issues */
        /* Some other files have more tile in horizontal direction than needed, so let's */
        /* accept that. But in that case we really need to keep the nTileX value for IReadBlock() */
        /* to work properly */
        if ((nW + 63) / 64 > nTileX || (nH + 63) / 64 > nTileY)
        {
            CPLDebug("OZI", "zoom[%d] unexpected number of tiles : nW=%d, nH=%d, nTileX=%d, nTileY=%d",
                     i, nW, nH, nTileX, nTileY);
            delete poDS;
            return NULL;
        }

        GDALColorTable* poColorTable = new GDALColorTable();
        GByte abyColorTable[256*4];
        VSIFReadL(abyColorTable, 1, 1024, fp);
        if (bOzi3)
            OZIDecrypt(abyColorTable, 1024, nKeyInit);
        int j;
        for(j=0;j<256;j++)
        {
            GDALColorEntry sEntry;
            sEntry.c1 = abyColorTable[4*j + 2];
            sEntry.c2 = abyColorTable[4*j + 1];
            sEntry.c3 = abyColorTable[4*j + 0];
            sEntry.c4 = 255;
            poColorTable->SetColorEntry(j, &sEntry);
        }

        poDS->papoBands[i] = new OZIRasterBand(poDS, i, nW, nH, nTileX, poColorTable);

        if (i > 0)
        {
            GByte* pabyTranslationTable =
                poDS->papoBands[i]->GetIndexColorTranslationTo(poDS->papoBands[0], NULL, NULL);

            delete poDS->papoBands[i]->poColorTable;
            poDS->papoBands[i]->poColorTable = poDS->papoBands[0]->poColorTable->Clone();
            poDS->papoBands[i]->pabyTranslationTable = pabyTranslationTable;
        }

    }

    poDS->SetBand(1, poDS->papoBands[0]);

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

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    return( poDS );
}
Esempio n. 30
0
OGRDataSource *OGRVRTDriver::Open( const char * pszFilename,
                                   int bUpdate )
{
    OGRVRTDataSource     *poDS;
    char *pszXML = NULL;

/* -------------------------------------------------------------------- */
/*      Are we being passed the XML definition directly?                */
/*      Skip any leading spaces/blanks.                                 */
/* -------------------------------------------------------------------- */
    const char *pszTestXML = pszFilename;
    while( *pszTestXML != '\0' && isspace( (unsigned char)*pszTestXML ) )
        pszTestXML++;

    if( EQUALN(pszTestXML,"<OGRVRTDataSource>",18) )
    {
        pszXML = CPLStrdup(pszTestXML);
    }

/* -------------------------------------------------------------------- */
/*      Open file and check if it contains appropriate XML.             */
/* -------------------------------------------------------------------- */
    else
    {
        VSILFILE *fp;
        char achHeader[512];

        fp = VSIFOpenL( pszFilename, "rb" );

        if( fp == NULL )
            return NULL;

        memset( achHeader, 0, sizeof(achHeader) );
        VSIFReadL( achHeader, 1, sizeof(achHeader)-1, fp );

        if( strstr(achHeader,"<OGRVRTDataSource") == NULL )
        {
            VSIFCloseL( fp );
            return NULL;
        }

        VSIStatBufL sStatBuf;
        if ( VSIStatL( pszFilename, &sStatBuf ) != 0 ||
             sStatBuf.st_size > 1024 * 1024 )
        {
            CPLDebug( "VRT", "Unreasonable long file, not likely really VRT" );
            VSIFCloseL( fp );
            return NULL;
        }

/* -------------------------------------------------------------------- */
/*      It is the right file, now load the full XML definition.         */
/* -------------------------------------------------------------------- */
        int nLen = (int) sStatBuf.st_size;

        VSIFSeekL( fp, 0, SEEK_SET );

        pszXML = (char *) VSIMalloc(nLen+1);
        if (pszXML == NULL)
        {
            VSIFCloseL( fp );
            return NULL;
        }
        pszXML[nLen] = '\0';
        if( ((int) VSIFReadL( pszXML, 1, nLen, fp )) != nLen )
        {
            CPLFree( pszXML );
            VSIFCloseL( fp );

            return NULL;
        }
        VSIFCloseL( fp );
    }

/* -------------------------------------------------------------------- */
/*      Parse the XML.                                                  */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psTree = CPLParseXMLString( pszXML );

    if( psTree == NULL )
    {
        CPLFree( pszXML );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      XML Validation.                                                 */
/* -------------------------------------------------------------------- */
    if( CSLTestBoolean(CPLGetConfigOption("GDAL_XML_VALIDATION", "YES")) )
    {
        const char* pszXSD = CPLFindFile( "gdal", "ogrvrt.xsd" );
        if( pszXSD != NULL )
        {
            std::vector<CPLString> aosErrors;
            CPLPushErrorHandlerEx(OGRVRTErrorHandler, &aosErrors);
            int bRet = CPLValidateXML(pszXML, pszXSD, NULL);
            CPLPopErrorHandler();
            if( !bRet )
            {
                if( aosErrors.size() > 0 &&
                    strstr(aosErrors[0].c_str(), "missing libxml2 support") == NULL )
                {
                    for(size_t i = 0; i < aosErrors.size(); i++)
                    {
                        CPLError(CE_Warning, CPLE_AppDefined, "%s", aosErrors[i].c_str());
                    }
                }
            }
            CPLErrorReset();
        }
    }
    CPLFree( pszXML );

/* -------------------------------------------------------------------- */
/*      Create a virtual datasource configured based on this XML input. */
/* -------------------------------------------------------------------- */
    poDS = new OGRVRTDataSource();
    poDS->SetDriver(this);
    /* psTree is owned by poDS */
    if( !poDS->Initialize( psTree, pszFilename, bUpdate ) )
    {
        delete poDS;
        return NULL;
    }

    return poDS;
}