예제 #1
0
int HF2Dataset::LoadBlockMap()
{
    if (bHasLoaderBlockMap)
        return panBlockOffset != NULL;

    bHasLoaderBlockMap = TRUE;

    const int nXBlocks = (nRasterXSize + nTileSize - 1) / nTileSize;
    const int nYBlocks = (nRasterYSize + nTileSize - 1) / nTileSize;
    panBlockOffset = (vsi_l_offset*) VSIMalloc3(sizeof(vsi_l_offset), nXBlocks, nYBlocks);
    if (panBlockOffset == NULL)
    {
        return FALSE;
    }
    for(int j = 0; j < nYBlocks; j++)
    {
        for(int i = 0; i < nXBlocks; i++)
        {
            vsi_l_offset nOff = VSIFTellL(fp);
            panBlockOffset[(nYBlocks - 1 - j) * nXBlocks + i] = nOff;
            //VSIFSeekL(fp, 4 + 4, SEEK_CUR);
            float fScale, fOff;
            VSIFReadL(&fScale, 4, 1, fp);
            VSIFReadL(&fOff, 4, 1, fp);
            CPL_LSBPTR32(&fScale);
            CPL_LSBPTR32(&fOff);
            //printf("fScale = %f, fOff = %f\n", fScale, fOff);
            const int nCols = MIN(nTileSize, nRasterXSize - nTileSize *i);
            const int nLines = MIN(nTileSize, nRasterYSize - nTileSize *j);
            for(int k = 0; k < nLines; k++)
            {
                GByte nWordSize;
                if( VSIFReadL(&nWordSize, 1, 1, fp) != 1 )
                {
                    CPLError(CE_Failure, CPLE_FileIO, "File too short");
                    VSIFree(panBlockOffset);
                    panBlockOffset = NULL;
                    return FALSE;
                }
                //printf("nWordSize=%d\n", nWordSize);
                if (nWordSize == 1 || nWordSize == 2 || nWordSize == 4)
                    VSIFSeekL(fp, static_cast<vsi_l_offset>(4 + nWordSize * (nCols - 1)), SEEK_CUR);
                else
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                            "Got unexpected byte depth (%d) for block (%d, %d) line %d",
                            (int)nWordSize, i, j, k);
                    VSIFree(panBlockOffset);
                    panBlockOffset = NULL;
                    return FALSE;
                }
            }
        }
    }

    return TRUE;
}
예제 #2
0
void TABRawBinBlock::Dump(FILE *fpOut /*=NULL*/)
{
    if (fpOut == NULL)
        fpOut = stdout;

    fprintf(fpOut, "----- TABRawBinBlock::Dump() -----\n");
    if (m_pabyBuf == NULL)
    {
        fprintf(fpOut, "Block has not been initialized yet.");
    }
    else
    {
        if( m_nBlockType == TABMAP_GARB_BLOCK )
        {
            fprintf(fpOut,"Garbage Block (type %d) at offset %d.\n",
                                                    m_nBlockType, m_nFileOffset);
            int nNextGarbageBlock = 0;
            memcpy(&nNextGarbageBlock, m_pabyBuf + 2, 4);
            CPL_LSBPTR32(&nNextGarbageBlock);
            fprintf(fpOut,"  m_nNextGarbageBlock     = %d\n", nNextGarbageBlock);
        }
        else
        {
            fprintf(fpOut, "Block (type %d) size=%d bytes at offset %d in file.\n",
                    m_nBlockType, m_nBlockSize, m_nFileOffset);
            fprintf(fpOut, "Current pointer at byte %d\n", m_nCurPos);
        }
    }

    fflush(fpOut);
}
예제 #3
0
파일: gtm.cpp 프로젝트: OSGeo/gdal
static int readInt(VSILFILE* fp)
{
    int val;
    VSIFReadL( &val, 1, 4, fp );
    CPL_LSBPTR32(&val);
    return val;
}
예제 #4
0
파일: gtm.cpp 프로젝트: OSGeo/gdal
static float readFloat(VSILFILE* fp)
{
    float val;
    VSIFReadL( &val, 1, 4, fp );
    CPL_LSBPTR32(&val);
    return val;
}
예제 #5
0
CPLErr GSBGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                   void * pImage )

{
    if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 )
        return CE_Failure;

    GSBGDataset *poGDS = reinterpret_cast<GSBGDataset *>(poDS);
    if( VSIFSeekL( poGDS->fp,
                   GSBGDataset::nHEADER_SIZE +
                        4 * static_cast<vsi_l_offset>(nRasterXSize) * (nRasterYSize - nBlockYOff - 1),
                   SEEK_SET ) != 0 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to seek to beginning of grid row.\n" );
        return CE_Failure;
    }

    if( VSIFReadL( pImage, sizeof(float), nBlockXSize,
                   poGDS->fp ) != static_cast<unsigned>(nBlockXSize) )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to read block from grid file.\n" );
        return CE_Failure;
    }

#ifdef CPL_MSB
    float *pfImage = (float *)pImage;
    for( int iPixel=0; iPixel<nBlockXSize; iPixel++ ) {
        CPL_LSBPTR32( pfImage+iPixel );
    }
#endif

    return CE_None;
}
예제 #6
0
int  TABRawBinBlock::WriteFloat(float fValue)
{
#ifdef CPL_MSB
    CPL_LSBPTR32(&fValue);
#endif

    return WriteBytes(4, (GByte*)&fValue);
}
예제 #7
0
static int ReadInt(VSILFILE* fp, int bOzi3 = FALSE, int nKeyInit = 0)
{
    int nVal;
    VSIFReadL(&nVal, 1, 4, fp);
    if (bOzi3) OZIDecrypt(&nVal, 4, (GByte) nKeyInit);
    CPL_LSBPTR32(&nVal);
    return nVal;
}
예제 #8
0
static int ReadInt(GByte**pptr)
{
    int nVal;
    memcpy(&nVal, *pptr, 4);
    *pptr += 4;
    CPL_LSBPTR32(&nVal);
    return nVal;
}
예제 #9
0
int  TABRawBinBlock::WriteFloat(float fValue)
{
#ifdef CPL_MSB
    CPL_LSBPTR32(&fValue);
#endif

    return WriteBytes(4, reinterpret_cast<GByte*>(&fValue));
}
예제 #10
0
bool TerragenDataset::get(float& value)
{
    if(1 == VSIFReadL(&value, sizeof(value), 1, m_fp))
    {
        CPL_LSBPTR32(&value);
        return true;
    }
    return false;
}
예제 #11
0
float   TABRawBinBlock::ReadFloat()
{
    float fValue = 0.0f;

    ReadBytes(4, (GByte*)(&fValue));

#ifdef CPL_MSB
    CPL_LSBPTR32(&fValue);
#endif
    return fValue;
}
예제 #12
0
float   TABRawBinBlock::ReadFloat()
{
    float fValue = 0.0f;

    ReadBytes(4, reinterpret_cast<GByte*>(&fValue));

#ifdef CPL_MSB
    CPL_LSBPTR32(&fValue);
#endif
    return fValue;
}
예제 #13
0
OGRErr Binary2WkbGeom(unsigned char *p, WKBGeometry* geom, int nBytes)
{
    GUInt32 i;

    if( nBytes < 28 )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "WalkGeom binary size (%d) too small",
                 nBytes);
        return OGRERR_FAILURE;
    }

    memcpy(&geom->wkbType, p, 4);
    CPL_LSBPTR32( &geom->wkbType );

    switch(geom->wkbType)
    {
    case wkbPoint:
    case wkbLineString:
    case wkbPolygon:
    case wkbMultiPoint:
    case wkbMultiLineString:
    case wkbMultiPolygon:
        return Binary2WkbMGeom(p, geom, nBytes);
    case wkbGeometryCollection:
        p += 4;
        memcpy(&geom->mgeometries.num_wkbSGeometries, p, 4);
        CPL_LSBPTR32( &geom->mgeometries.num_wkbSGeometries );
        p += 4;
        geom->mgeometries.WKBGeometries =
            new WKBSimpleGeometry[geom->mgeometries.num_wkbSGeometries];

        for(i = 0; i < geom->mgeometries.num_wkbSGeometries; i++)
            Binary2WkbMGeom(p, (WKBGeometry*)(&geom->mgeometries.WKBGeometries[i]), nBytes-8);
        break;
    default:
        geom->wkbType=wkbUnknown;
        return OGRERR_FAILURE;
    }
    return OGRERR_NONE;
}
예제 #14
0
OGRIdrisiLayer::OGRIdrisiLayer( const char* pszFilename,
                                const char* pszLayerName,
                                VSILFILE* fp,
                                OGRwkbGeometryType eGeomType,
                                const char* pszWTKString )

{
    this->fp = fp;
    this->eGeomType = eGeomType;
    nNextFID = 1;
    bEOF = FALSE;
    fpAVL = NULL;

    if (pszWTKString)
    {
        poSRS = new OGRSpatialReference();
        char* pszTmp = (char*)pszWTKString;
        poSRS->importFromWkt(&pszTmp);
    }
    else
        poSRS = NULL;

    poFeatureDefn = new OGRFeatureDefn( pszLayerName );
    SetDescription( poFeatureDefn->GetName() );
    poFeatureDefn->Reference();
    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
    poFeatureDefn->SetGeomType( eGeomType );

    OGRFieldDefn oFieldDefn("id", OFTReal);
    poFeatureDefn->AddFieldDefn( &oFieldDefn );

    bExtentValid = FALSE;
    dfMinX = dfMinY = dfMaxX = dfMaxY = 0.0;

    VSIFSeekL( fp, 1, SEEK_SET );
    if (VSIFReadL( &nTotalFeatures, sizeof(unsigned int), 1, fp ) != 1)
        nTotalFeatures = 0;
    CPL_LSBPTR32(&nTotalFeatures);

    if (nTotalFeatures != 0)
    {
        if (!Detect_AVL_ADC(pszFilename))
        {
            if( fpAVL != NULL )
                VSIFCloseL( fpAVL );
            fpAVL = NULL;
        }
    }

    ResetReading();
}
예제 #15
0
bool LevellerDataset::get(int& n, VSILFILE* fp, const char* psz)
{
    vsi_l_offset offset;
    size_t		 len;

    if(this->locate_data(offset, len, fp, psz))
    {
        GInt32 value;
        if(1 == VSIFReadL(&value, sizeof(value), 1, fp))
        {
            CPL_LSBPTR32(&value);
            n = (int)value;
            return true;
        }
    }	
    return false;
}
예제 #16
0
CPLErr BTRasterBand::SetUnitType(const char* psz)
{
    BTDataset& ds = *(BTDataset*)poDS;
    if(EQUAL(psz, "m"))
        ds.m_fVscale = 1.0f;
    else if(EQUAL(psz, "ft"))
        ds.m_fVscale = 0.3048f;
    else if(EQUAL(psz, "sft"))
        ds.m_fVscale = 1200.0f / 3937.0f;
    else
        return CE_Failure;

    float fScale = ds.m_fVscale;

    CPL_LSBPTR32(&fScale);

    // Update header's elevation scale field.
    memcpy(ds.abyHeader + 62, &fScale, sizeof(fScale));

    ds.bHeaderModified = TRUE;
    return CE_None;
}
예제 #17
0
GDALDataset *LOSLASDataset::Open( GDALOpenInfo * poOpenInfo )

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

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

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

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

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    CPL_IGNORE_RET_VAL(VSIFSeekL( poDS->fpImage, 64, SEEK_SET ));

    CPL_IGNORE_RET_VAL(VSIFReadL( &(poDS->nRasterXSize), 4, 1, poDS->fpImage ));
    CPL_IGNORE_RET_VAL(VSIFReadL( &(poDS->nRasterYSize), 4, 1, poDS->fpImage ));

    CPL_LSBPTR32( &(poDS->nRasterXSize) );
    CPL_LSBPTR32( &(poDS->nRasterYSize) );

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

    CPL_IGNORE_RET_VAL(VSIFSeekL( poDS->fpImage, 76, SEEK_SET ));

    float min_lon, min_lat, delta_lon, delta_lat;

    CPL_IGNORE_RET_VAL(VSIFReadL( &min_lon, 4, 1, poDS->fpImage ));
    CPL_IGNORE_RET_VAL(VSIFReadL( &delta_lon, 4, 1, poDS->fpImage ));
    CPL_IGNORE_RET_VAL(VSIFReadL( &min_lat, 4, 1, poDS->fpImage ));
    CPL_IGNORE_RET_VAL(VSIFReadL( &delta_lat, 4, 1, poDS->fpImage ));

    CPL_LSBPTR32( &min_lon );
    CPL_LSBPTR32( &delta_lon );
    CPL_LSBPTR32( &min_lat );
    CPL_LSBPTR32( &delta_lat );

    poDS->nRecordLength = poDS->nRasterXSize * 4 + 4;

/* -------------------------------------------------------------------- */
/*      Create band information object.                                 */
/*                                                                      */
/*      Note we are setting up to read from the last image record to    */
/*      the first since the data comes with the southern most record    */
/*      first, not the northernmost like we would want.                 */
/* -------------------------------------------------------------------- */
    poDS->SetBand(
        1, new RawRasterBand( poDS, 1, poDS->fpImage,
                              poDS->nRasterYSize * poDS->nRecordLength + 4,
                              4, -1 * poDS->nRecordLength,
                              GDT_Float32,
                              CPL_IS_LSB, TRUE, FALSE ) );

/* -------------------------------------------------------------------- */
/*      Setup georeferencing.                                           */
/* -------------------------------------------------------------------- */
    poDS->adfGeoTransform[0] = min_lon - delta_lon*0.5;
    poDS->adfGeoTransform[1] = delta_lon;
    poDS->adfGeoTransform[2] = 0.0;
    poDS->adfGeoTransform[3] = min_lat + (poDS->nRasterYSize-0.5) * delta_lat;
    poDS->adfGeoTransform[4] = 0.0;
    poDS->adfGeoTransform[5] = -1 * delta_lat;

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

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

    return( poDS );
}
예제 #18
0
OGRFeature *OGRIdrisiLayer::GetNextRawFeature()
{
    while(TRUE)
    {
        if (eGeomType == wkbPoint)
        {
            double dfId;
            double dfX, dfY;
            if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfX, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfY, sizeof(double), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR64(&dfId);
            CPL_LSBPTR64(&dfX);
            CPL_LSBPTR64(&dfY);

            if (m_poFilterGeom != NULL &&
                (dfX < m_sFilterEnvelope.MinX ||
                 dfX > m_sFilterEnvelope.MaxX ||
                 dfY < m_sFilterEnvelope.MinY ||
                 dfY > m_sFilterEnvelope.MaxY))
            {
                nNextFID ++;
                continue;
            }

            OGRPoint* poGeom = new OGRPoint(dfX, dfY);
            if (poSRS)
                poGeom->assignSpatialReference(poSRS);
            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetField(0, dfId);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetGeometryDirectly(poGeom);
            ReadAVLLine(poFeature);
            return poFeature;
        }
        else if (eGeomType == wkbLineString)
        {
            double dfId;
            double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape;
            unsigned int nNodes;

            if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR64(&dfId);
            CPL_LSBPTR64(&dfMinXShape);
            CPL_LSBPTR64(&dfMaxXShape);
            CPL_LSBPTR64(&dfMinYShape);
            CPL_LSBPTR64(&dfMaxYShape);

            if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR32(&nNodes);

            if (nNodes > 100 * 1000 * 1000)
                return NULL;

            if (m_poFilterGeom != NULL &&
                (dfMaxXShape < m_sFilterEnvelope.MinX ||
                 dfMinXShape > m_sFilterEnvelope.MaxX ||
                 dfMaxYShape < m_sFilterEnvelope.MinY ||
                 dfMinYShape > m_sFilterEnvelope.MaxY))
            {
                nNextFID ++;
                VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR);
                continue;
            }

            OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nNodes);
            if (poRawPoints == NULL)
            {
                return NULL;
            }

            if ((unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes)
            {
                VSIFree(poRawPoints);
                return NULL;
            }

#if defined(CPL_MSB)
            for(unsigned int iNode=0; iNode<nNodes; iNode++)
            {
                CPL_LSBPTR64(&poRawPoints[iNode].x);
                CPL_LSBPTR64(&poRawPoints[iNode].y);
            }
#endif

            OGRLineString* poGeom = new OGRLineString();
            poGeom->setPoints(nNodes, poRawPoints, NULL);

            VSIFree(poRawPoints);

            if (poSRS)
                poGeom->assignSpatialReference(poSRS);
            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetField(0, dfId);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetGeometryDirectly(poGeom);
            ReadAVLLine(poFeature);
            return poFeature;
        }
        else /* if (eGeomType == wkbPolygon) */
        {
            double dfId;
            double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape;
            unsigned int nParts;
            unsigned int nTotalNodes;

            if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR64(&dfId);
            CPL_LSBPTR64(&dfMinXShape);
            CPL_LSBPTR64(&dfMaxXShape);
            CPL_LSBPTR64(&dfMinYShape);
            CPL_LSBPTR64(&dfMaxYShape);
            if (VSIFReadL(&nParts, sizeof(unsigned int), 1, fp) != 1 ||
                VSIFReadL(&nTotalNodes, sizeof(unsigned int), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR32(&nParts);
            CPL_LSBPTR32(&nTotalNodes);

            if (nParts > 100000 || nTotalNodes > 100 * 1000 * 1000)
                return NULL;

            if (m_poFilterGeom != NULL &&
                (dfMaxXShape < m_sFilterEnvelope.MinX ||
                 dfMinXShape > m_sFilterEnvelope.MaxX ||
                 dfMaxYShape < m_sFilterEnvelope.MinY ||
                 dfMinYShape > m_sFilterEnvelope.MaxY))
            {
                VSIFSeekL(fp, sizeof(unsigned int) * nParts + sizeof(OGRRawPoint) * nTotalNodes, SEEK_CUR);
                nNextFID ++;
                continue;
            }

            OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nTotalNodes);
            if (poRawPoints == NULL)
            {
                return NULL;
            }
            unsigned int* panNodesCount = NULL;
            if( nParts > 1 )
            {
                panNodesCount = (unsigned int *)CPLMalloc(sizeof(unsigned int) * nParts);
                if (VSIFReadL(panNodesCount, sizeof(unsigned int) * nParts, 1, fp) != 1)
                {
                    VSIFree(poRawPoints);
                    VSIFree(panNodesCount);
                    return NULL;
                }
#if defined(CPL_MSB)
                for(unsigned int iPart=0; iPart < nParts; iPart ++)
                {
                    CPL_LSBPTR32(&panNodesCount[iPart]);
                }
#endif
            }
            else
            {
                unsigned int nNodes;
                if (VSIFReadL(&nNodes, sizeof(unsigned int) * nParts, 1, fp) != 1)
                {
                    VSIFree(poRawPoints);
                    return NULL;
                }
                CPL_LSBPTR32(&nNodes);
                if( nNodes != nTotalNodes )
                {
                    VSIFree(poRawPoints);
                    return NULL;
                }
            }

            unsigned int iPart;
            OGRPolygon* poGeom = new OGRPolygon();
            for(iPart = 0; iPart < nParts; iPart ++)
            {
                unsigned int nNodes = (nParts > 1) ? panNodesCount[iPart] : nTotalNodes;
                if (nNodes > nTotalNodes ||
                    (unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes)
                {
                    VSIFree(poRawPoints);
                    VSIFree(panNodesCount);
                    delete poGeom;
                    return NULL;
                }

#if defined(CPL_MSB)
                for(unsigned int iNode=0; iNode<nNodes; iNode++)
                {
                    CPL_LSBPTR64(&poRawPoints[iNode].x);
                    CPL_LSBPTR64(&poRawPoints[iNode].y);
                }
#endif

                OGRLinearRing* poLR = new OGRLinearRing();
                poGeom->addRingDirectly(poLR);
                poLR->setPoints(nNodes, poRawPoints, NULL);
            }

            VSIFree(poRawPoints);
            VSIFree(panNodesCount);

            if (poSRS)
                poGeom->assignSpatialReference(poSRS);
            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetField(0, dfId);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetGeometryDirectly(poGeom);
            ReadAVLLine(poFeature);
            return poFeature;
        }
    }
}
예제 #19
0
파일: gtm.cpp 프로젝트: OSGeo/gdal
void appendInt(void* pBuffer, int val)
{
    CPL_LSBPTR32(&val);
    memcpy(pBuffer, &val, 4);
}
예제 #20
0
static void WriteInt(VSILFILE* fp, GInt32 val)
{
    CPL_LSBPTR32(&val);
    VSIFWriteL(&val, 4, 1, fp);
}
예제 #21
0
static void WriteFloat(VSILFILE* fp, float val)
{
    CPL_LSBPTR32(&val);
    VSIFWriteL(&val, 4, 1, fp);
}
예제 #22
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 += ((signed 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;
}
예제 #23
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 explicitly 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->GetSiblingFiles());
    }

/* -------------------------------------------------------------------- */
/*      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 );
}
예제 #24
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;
    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;
    }

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

    CPL_LSBPTR32( &nSize );

    GInt32 nVersion;
    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(GUInt32), 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_CUR ) != 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;
}
예제 #25
0
GDALDataset *GSCDataset::Open( GDALOpenInfo * poOpenInfo )

{
    int		nPixels, nLines, i, nRecordLen;

/* -------------------------------------------------------------------- */
/*      Does this plausible look like a GSC Geogrid file?               */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 20 )
        return NULL;

    if( poOpenInfo->pabyHeader[12] != 0x02
        || poOpenInfo->pabyHeader[13] != 0x00
        || poOpenInfo->pabyHeader[14] != 0x00
        || poOpenInfo->pabyHeader[15] != 0x00 )
        return NULL;

    nRecordLen = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[0]);
    nPixels = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[1]);
    nLines  = CPL_LSBWORD32(((GInt32 *) poOpenInfo->pabyHeader)[2]);

    if( nPixels < 1 || nLines < 1 || nPixels > 100000 || nLines > 100000 )
        return NULL;

    if( nRecordLen != nPixels * 4 )
        return NULL;
        
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The GSC driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
    nRecordLen += 8; /* for record length markers */

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

    poDS = new GSCDataset();

    poDS->nRasterXSize = nPixels;
    poDS->nRasterYSize = nLines;

/* -------------------------------------------------------------------- */
/*      Assume ownership of the file handled from the GDALOpenInfo.     */
/* -------------------------------------------------------------------- */
    poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (poDS->fpImage == NULL)
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the header information in the second record. 		*/
/* -------------------------------------------------------------------- */
    float	afHeaderInfo[8];

    if( VSIFSeekL( poDS->fpImage, nRecordLen + 12, SEEK_SET ) != 0
        || VSIFReadL( afHeaderInfo, sizeof(float), 8, poDS->fpImage ) != 8 )
    {
        CPLError( CE_Failure, CPLE_FileIO, 
                  "Failure reading second record of GSC file with %d record length.",
                  nRecordLen );
        delete poDS;
        return NULL;
    }

    for( i = 0; i < 8; i++ )
    {
        CPL_LSBPTR32( afHeaderInfo + i );
    }

    poDS->adfGeoTransform[0] = afHeaderInfo[2];
    poDS->adfGeoTransform[1] = afHeaderInfo[0];
    poDS->adfGeoTransform[2] = 0.0;
    poDS->adfGeoTransform[3] = afHeaderInfo[5];
    poDS->adfGeoTransform[4] = 0.0;
    poDS->adfGeoTransform[5] = -afHeaderInfo[1];
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    RawRasterBand *poBand;
#ifdef CPL_LSB
    int	bNative = TRUE;
#else
    int bNative = FALSE;
#endif

    poBand = new RawRasterBand( poDS, 1, poDS->fpImage,
                                nRecordLen * 2 + 4,
                                sizeof(float), nRecordLen,
                                GDT_Float32, bNative, TRUE );
    poDS->SetBand( 1, poBand );

    poBand->SetNoDataValue( -1.0000000150474662199e+30 );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();
    
/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #26
0
OGRErr OGRCreateFromGeomedia( GByte *pabyGeom,
                              OGRGeometry **ppoGeom,
                              int nBytes )

{
    *ppoGeom = NULL;

    if( nBytes < 16 )
        return OGRERR_FAILURE;

    if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) )
        return OGRERR_FAILURE;

    int nGeomType = pabyGeom[0];
    pabyGeom += 16;
    nBytes -= 16;

    if( nGeomType == GEOMEDIA_POINT ||
        nGeomType == GEOMEDIA_ORIENTED_POINT )
    {
        if (nBytes < 3 * 8)
            return OGRERR_FAILURE;

        double dfX, dfY, dfZ;
        memcpy(&dfX, pabyGeom, 8);
        CPL_LSBPTR64(&dfX);
        memcpy(&dfY, pabyGeom + 8, 8);
        CPL_LSBPTR64(&dfY);
        memcpy(&dfZ, pabyGeom + 16, 8);
        CPL_LSBPTR64(&dfZ);

        *ppoGeom = new OGRPoint( dfX, dfY, dfZ );

         return OGRERR_NONE;
    }
    else if ( nGeomType == GEOMEDIA_POLYLINE )
    {
        if (nBytes < 4)
            return OGRERR_FAILURE;

        int nPoints;
        memcpy(&nPoints, pabyGeom, 4);
        CPL_LSBPTR32(&nPoints);

        pabyGeom += 4;
        nBytes -= 4;

        if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24)
            return OGRERR_FAILURE;

        OGRLineString* poLS = new OGRLineString();
        poLS->setNumPoints(nPoints);
        int i;
        for(i=0;i<nPoints;i++)
        {
            double dfX, dfY, dfZ;
            memcpy(&dfX, pabyGeom, 8);
            CPL_LSBPTR64(&dfX);
            memcpy(&dfY, pabyGeom + 8, 8);
            CPL_LSBPTR64(&dfY);
            memcpy(&dfZ, pabyGeom + 16, 8);
            CPL_LSBPTR64(&dfZ);

            poLS->setPoint(i, dfX, dfY, dfZ);

            pabyGeom += 24;
        }

        *ppoGeom = poLS;

        return OGRERR_NONE;
    }
    else if ( nGeomType == GEOMEDIA_POLYGON )
    {
        if (nBytes < 4)
            return OGRERR_FAILURE;

        int nPoints;
        memcpy(&nPoints, pabyGeom, 4);
        CPL_LSBPTR32(&nPoints);

        pabyGeom += 4;
        nBytes -= 4;

        if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24)
            return OGRERR_FAILURE;

        OGRLinearRing* poRing = new OGRLinearRing();
        poRing->setNumPoints(nPoints);
        int i;
        for(i=0;i<nPoints;i++)
        {
            double dfX, dfY, dfZ;
            memcpy(&dfX, pabyGeom, 8);
            CPL_LSBPTR64(&dfX);
            memcpy(&dfY, pabyGeom + 8, 8);
            CPL_LSBPTR64(&dfY);
            memcpy(&dfZ, pabyGeom + 16, 8);
            CPL_LSBPTR64(&dfZ);

            poRing->setPoint(i, dfX, dfY, dfZ);

            pabyGeom += 24;
        }

        OGRPolygon* poPoly = new OGRPolygon();
        poPoly->addRingDirectly(poRing);
        *ppoGeom = poPoly;

        return OGRERR_NONE;
    }
    else if ( nGeomType == GEOMEDIA_BOUNDARY )
    {
        if (nBytes < 4)
            return OGRERR_FAILURE;

        int nExteriorSize;
        memcpy(&nExteriorSize, pabyGeom, 4);
        CPL_LSBPTR32(&nExteriorSize);

        pabyGeom += 4;
        nBytes -= 4;

        if (nBytes < nExteriorSize)
            return OGRERR_FAILURE;

        OGRGeometry* poExteriorGeom = NULL;
        if (OGRCreateFromGeomedia( pabyGeom, &poExteriorGeom, nExteriorSize ) != OGRERR_NONE)
            return OGRERR_FAILURE;

        if ( wkbFlatten( poExteriorGeom->getGeometryType() ) != wkbPolygon )
        {
            delete poExteriorGeom;
            return OGRERR_FAILURE;
        }

        pabyGeom += nExteriorSize;
        nBytes -= nExteriorSize;

        if (nBytes < 4)
        {
            delete poExteriorGeom;
            return OGRERR_FAILURE;
        }

        int nInteriorSize;
        memcpy(&nInteriorSize, pabyGeom, 4);
        CPL_LSBPTR32(&nInteriorSize);

        pabyGeom += 4;
        nBytes -= 4;

        if (nBytes < nInteriorSize)
        {
            delete poExteriorGeom;
            return OGRERR_FAILURE;
        }

        OGRGeometry* poInteriorGeom = NULL;
        if (OGRCreateFromGeomedia( pabyGeom, &poInteriorGeom, nInteriorSize ) != OGRERR_NONE)
        {
            delete poExteriorGeom;
            return OGRERR_FAILURE;
        }

        OGRwkbGeometryType interiorGeomType = wkbFlatten( poInteriorGeom->getGeometryType() );
        if ( interiorGeomType == wkbPolygon )
        {
            ((OGRPolygon*)poExteriorGeom)->addRing(((OGRPolygon*)poInteriorGeom)->getExteriorRing());
        }
        else if ( interiorGeomType == wkbMultiPolygon )
        {
            int numGeom = ((OGRMultiPolygon*)poInteriorGeom)->getNumGeometries();
            for ( int i = 0; i < numGeom; ++i )
            {
                OGRPolygon* poInteriorPolygon = 
                    (OGRPolygon*)((OGRMultiPolygon*)poInteriorGeom)->getGeometryRef(i);
                ((OGRPolygon*)poExteriorGeom)->addRing( poInteriorPolygon->getExteriorRing() );
            }
        }
        else
        {
            delete poExteriorGeom;
            delete poInteriorGeom;
            return OGRERR_FAILURE;
        }

        delete poInteriorGeom;
        *ppoGeom = poExteriorGeom;

        return OGRERR_NONE;
    }
    else if ( nGeomType == GEOMEDIA_COLLECTION ||
              nGeomType == GEOMEDIA_MULTILINE ||
              nGeomType == GEOMEDIA_MULTIPOLYGON )
    {
        if (nBytes < 4)
            return OGRERR_FAILURE;

        int i;
        int nParts;
        memcpy(&nParts, pabyGeom, 4);
        CPL_LSBPTR32(&nParts);

        pabyGeom += 4;
        nBytes -= 4;

        if (nParts < 0 || nParts > INT_MAX / (4 + 16) || nBytes < nParts * (4 + 16))
            return OGRERR_FAILURE;

        /* Can this collection be considered as a multipolyline or multipolygon ? */
        if ( nGeomType == GEOMEDIA_COLLECTION )
        {
            GByte* pabyGeomBackup = pabyGeom;
            int nBytesBackup = nBytes;

            int bAllPolyline = TRUE;
            int bAllPolygon = TRUE;

            for(i=0;i<nParts;i++)
            {
                if (nBytes < 4)
                    return OGRERR_FAILURE;
                int nSubBytes;
                memcpy(&nSubBytes, pabyGeom, 4);
                CPL_LSBPTR32(&nSubBytes);

                if (nSubBytes < 0)
                {
                    return OGRERR_FAILURE;
                }

                pabyGeom += 4;
                nBytes -= 4;

                if (nBytes < nSubBytes)
                {
                    return OGRERR_FAILURE;
                }

                if( nSubBytes < 16 )
                    return OGRERR_FAILURE;

                if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) )
                    return OGRERR_FAILURE;

                int nSubGeomType = pabyGeom[0];
                if ( nSubGeomType != GEOMEDIA_POLYLINE )
                    bAllPolyline = FALSE;
                if ( nSubGeomType != GEOMEDIA_POLYGON )
                    bAllPolygon = FALSE;

                pabyGeom += nSubBytes;
                nBytes -= nSubBytes;
            }

            pabyGeom = pabyGeomBackup;
            nBytes = nBytesBackup;

            if (bAllPolyline)
                nGeomType = GEOMEDIA_MULTILINE;
            else if (bAllPolygon)
                nGeomType = GEOMEDIA_MULTIPOLYGON;
        }

        OGRGeometryCollection* poColl = (nGeomType == GEOMEDIA_MULTILINE) ? new OGRMultiLineString() :
                                        (nGeomType == GEOMEDIA_MULTIPOLYGON) ? new OGRMultiPolygon() :
                                                              new OGRGeometryCollection();

        for(i=0;i<nParts;i++)
        {
            if (nBytes < 4)
                return OGRERR_FAILURE;
            int nSubBytes;
            memcpy(&nSubBytes, pabyGeom, 4);
            CPL_LSBPTR32(&nSubBytes);

            if (nSubBytes < 0)
            {
                delete poColl;
                return OGRERR_FAILURE;
            }

            pabyGeom += 4;
            nBytes -= 4;

            if (nBytes < nSubBytes)
            {
                delete poColl;
                return OGRERR_FAILURE;
            }

            OGRGeometry* poSubGeom = NULL;
            if (OGRCreateFromGeomedia( pabyGeom, &poSubGeom, nSubBytes ) == OGRERR_NONE)
            {
                if (wkbFlatten(poColl->getGeometryType()) == wkbMultiPolygon &&
                    wkbFlatten(poSubGeom->getGeometryType()) == wkbLineString)
                {
                    OGRPolygon* poPoly = new OGRPolygon();
                    OGRLinearRing* poRing = new OGRLinearRing();
                    poRing->addSubLineString((OGRLineString*)poSubGeom);
                    poPoly->addRingDirectly(poRing);
                    delete poSubGeom;
                    poSubGeom = poPoly;
                }

                if (poColl->addGeometryDirectly(poSubGeom) != OGRERR_NONE)
                {
                    //printf("%d %d\n", poColl->getGeometryType() & ~wkb25DBit, poSubGeom->getGeometryType() & ~wkb25DBit);
                    delete poSubGeom;
                }
            }

            pabyGeom += nSubBytes;
            nBytes -= nSubBytes;
        }

        *ppoGeom = poColl;

        return OGRERR_NONE;
    }
    else
    {
        CPLDebug("GEOMEDIA", "Unhandled type %d", nGeomType);
    }

    return OGRERR_FAILURE;
}
예제 #27
0
bool LevellerDataset::write(size_t n)
{
	CPL_LSBPTR32(&n);
	return (1 == VSIFWriteL(&n, sizeof(n), 1, m_fp));
}
예제 #28
0
bool TerragenDataset::put(float f)
{
    CPL_LSBPTR32(&f);
    return( 1 == VSIFWriteL(&f, sizeof(f), 1, m_fp) );
}
예제 #29
0
GDALDataset *BTDataset::Create( const char * pszFilename,
                                int nXSize,
                                int nYSize,
                                int nBands,
                                GDALDataType eType,
                                CPL_UNUSED char ** papszOptions )
{

/* -------------------------------------------------------------------- */
/*      Verify input options.                                           */
/* -------------------------------------------------------------------- */
    if( eType != GDT_Int16 && eType != GDT_Int32 && eType != GDT_Float32 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
              "Attempt to create .bt dataset with an illegal "
              "data type (%s), only Int16, Int32 and Float32 supported.",
              GDALGetDataTypeName(eType) );

        return NULL;
    }

    if( nBands != 1 )
    {
        CPLError(
            CE_Failure, CPLE_AppDefined,
            "Attempt to create .bt dataset with %d bands, only 1 supported",
            nBands );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try to create the file.                                         */
/* -------------------------------------------------------------------- */
    VSILFILE *fp = VSIFOpenL( pszFilename, "wb" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Attempt to create file `%s' failed.",
                  pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Setup base header.                                              */
/* -------------------------------------------------------------------- */
    unsigned char abyHeader[256] = {};

    memcpy( abyHeader, "binterr1.3", 10 );

    GInt32 nTemp = CPL_LSBWORD32( nXSize );
    memcpy( abyHeader+10, &nTemp, 4 );

    nTemp = CPL_LSBWORD32( nYSize );
    memcpy( abyHeader+14, &nTemp, 4 );

    GInt16 nShortTemp = static_cast<GInt16>(
         CPL_LSBWORD16( (GInt16)(GDALGetDataTypeSize( eType ) / 8 )) );
    memcpy( abyHeader + 18, &nShortTemp, 2 );

    if( eType == GDT_Float32 )
        abyHeader[20] = 1;
    else
        abyHeader[20] = 0;

    nShortTemp = CPL_LSBWORD16( 1 ); /* meters */
    memcpy( abyHeader + 22, &nShortTemp, 2 );

    nShortTemp = CPL_LSBWORD16( 0 ); /* not utm */
    memcpy( abyHeader + 24, &nShortTemp, 2 );

    nShortTemp = CPL_LSBWORD16( -2 ); /* datum unknown */
    memcpy( abyHeader + 26, &nShortTemp, 2 );

/* -------------------------------------------------------------------- */
/*      Set dummy extents.                                              */
/* -------------------------------------------------------------------- */
    double dfLeft = 0.0;
    double dfRight = nXSize;
    double dfTop = nYSize;
    double dfBottom = 0.0;

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

    CPL_LSBPTR64( abyHeader + 28 );
    CPL_LSBPTR64( abyHeader + 36 );
    CPL_LSBPTR64( abyHeader + 44 );
    CPL_LSBPTR64( abyHeader + 52 );

/* -------------------------------------------------------------------- */
/*      Set dummy scale.                                                */
/* -------------------------------------------------------------------- */
    float fScale = 1.0;

    memcpy( abyHeader + 62, &fScale, 4 );
    CPL_LSBPTR32( abyHeader + 62 );

/* -------------------------------------------------------------------- */
/*      Write to disk.                                                  */
/* -------------------------------------------------------------------- */
    if( VSIFWriteL( (void *) abyHeader, 256, 1, fp ) != 1 ||
        VSIFSeekL( fp, (GDALGetDataTypeSize(eType)/8) * nXSize * (vsi_l_offset)nYSize - 1,
                   SEEK_CUR ) != 0
        || VSIFWriteL( abyHeader+255, 1, 1, fp ) != 1 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Failed to extent file to its full size, out of disk space?"
                  );

        CPL_IGNORE_RET_VAL(VSIFCloseL( fp ));
        VSIUnlink( pszFilename );
        return NULL;
    }

    if( VSIFCloseL( fp ) != 0 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Failed to extent file to its full size, out of disk space?"
                  );
        VSIUnlink( pszFilename );
        return NULL;
    }

    return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
}
예제 #30
0
GDALDataset *BTDataset::Open( GDALOpenInfo * poOpenInfo )

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

    if( !STARTS_WITH((const char *) poOpenInfo->pabyHeader, "binterr") )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    BTDataset *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 = static_cast<int>(CPLAtof(szVersion) * 10);

/* -------------------------------------------------------------------- */
/*      Extract core header information, being careful about the        */
/*      version.                                                        */
/* -------------------------------------------------------------------- */

    GInt32 nIntTemp = 0;
    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;
    }

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

    GDALDataType eType = GDT_Unknown;
    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 = VSIFOpenL( pszPrjFile, "rt" );
        if( fp != NULL )
        {
            const int nBufMax = 10000;

            char *pszBuffer = static_cast<char *>(CPLMalloc(nBufMax));
            const int nBytes =
                static_cast<int>(VSIFReadL( pszBuffer, 1, nBufMax-1, fp ));
            CPL_IGNORE_RET_VAL(VSIFCloseL( fp ));

            pszBuffer[nBytes] = '\0';

            char *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 = 0;
        memcpy( &nUTMZone, poDS->abyHeader + 24, 2 );
        nUTMZone = CPL_LSBWORD16( nUTMZone );

        GInt16 nDatum = 0;
        memcpy( &nDatum, poDS->abyHeader + 26, 2 );
        nDatum = CPL_LSBWORD16( nDatum );

        GInt16 nHUnits = 0;
        memcpy( &nHUnits, poDS->abyHeader + 22, 2 );
        nHUnits = CPL_LSBWORD16( nHUnits );

        if( nUTMZone != 0 )
            oSRS.SetUTM( std::abs(static_cast<int>(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, CPLAtof(SRS_UL_FOOT_CONV) );
        else if( nHUnits == 3 )
            oSRS.SetLinearUnits( SRS_UL_US_FOOT, CPLAtof(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];
                snprintf( szName, sizeof(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 = 0.0;
        memcpy( &dfLeft, poDS->abyHeader + 28, 8 );
        CPL_LSBPTR64( &dfLeft );

        double dfRight = 0.0;
        memcpy( &dfRight, poDS->abyHeader + 36, 8 );
        CPL_LSBPTR64( &dfRight );

        double dfBottom = 0.0;
        memcpy( &dfBottom, poDS->abyHeader + 44, 8 );
        CPL_LSBPTR64( &dfBottom );

        double dfTop = 0.0;
        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 );
        delete poDS;
        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;
}