Exemple #1
0
int main(int argc, char* argv[])
{
    int i;
    int nThreads = CPLGetNumCPUs();
    std::vector<CPLJoinableThread*> apsThreads;
    Strategy eStrategy = STRATEGY_RANDOM;
    int bNewDatasetOption = FALSE;
    int nXSize = 5000;
    int nYSize = 5000;
    int nBands = 4;
    char** papszOptions = NULL;
    int bOnDisk = FALSE;
    std::vector<ThreadDescription> asThreadDescription;
    int bMemDriver = FALSE;
    GDALDataset* poMEMDS = NULL;
    int bMigrate = FALSE;
    int nMaxRequests = -1;

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );

    GDALAllRegister();

    for(i = 1; i < argc; i++)
    {
        if( EQUAL(argv[i], "-threads") && i + 1 < argc)
        {
            i ++;
            nThreads = atoi(argv[i]);
        }
        else if( EQUAL(argv[i], "-loops") && i + 1 < argc)
        {
            i ++;
            nLoops = atoi(argv[i]);
            if( nLoops <= 0 )
                nLoops = INT_MAX;
        }
        else if( EQUAL(argv[i], "-max_requests") && i + 1 < argc)
        {
            i ++;
            nMaxRequests = atoi(argv[i]);
        }
        else if( EQUAL(argv[i], "-strategy") && i + 1 < argc)
        {
            i ++;
            if( EQUAL(argv[i], "random") )
                eStrategy = STRATEGY_RANDOM;
            else if( EQUAL(argv[i], "line") )
                eStrategy = STRATEGY_LINE;
            else if( EQUAL(argv[i], "block") )
                eStrategy = STRATEGY_BLOCK;
            else
                Usage();
        }
        else if( EQUAL(argv[i], "-xsize") && i + 1 < argc)
        {
            i ++;
            nXSize = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-ysize") && i + 1 < argc)
        {
            i ++;
            nYSize = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-bands") && i + 1 < argc)
        {
            i ++;
            nBands = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-co") && i + 1 < argc)
        {
            i ++;
            papszOptions = CSLAddString(papszOptions, argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-ondisk"))
        {
            bOnDisk = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-check"))
        {
            bCheck = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-memdriver"))
        {
            bMemDriver = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-migrate"))
            bMigrate = TRUE;
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszDataset == NULL )
            pszDataset = argv[i];
        else
        {
            Usage();
        }
    }

    if( pszDataset != NULL && bNewDatasetOption )
        Usage();

    CPLDebug("TEST", "Using %d threads", nThreads);

    int bCreatedDataset = FALSE;
    if( pszDataset == NULL )
    {
        bCreatedDataset = TRUE;
        if( bOnDisk )
            pszDataset = "/tmp/tmp.tif";
        else
            pszDataset = "/vsimem/tmp.tif";
        GDALDataset* poDS = ((GDALDriver*)GDALGetDriverByName((bMemDriver) ? "MEM" : "GTiff"))->Create(pszDataset,
                                nXSize, nYSize, nBands, GDT_Byte, papszOptions);
        if( bCheck )
        {
            GByte* pabyLine = (GByte*) VSIMalloc(nBands * nXSize);
            for(int iY=0;iY<nYSize;iY++)
            {
                for(int iX=0;iX<nXSize;iX++)
                {
                    for(int iBand=0;iBand<nBands;iBand++)
                    {
                        unsigned long seed = iBand * nXSize * nYSize + iY * nXSize + iX;
                        pabyLine[iBand * nXSize + iX] = (GByte)myrand_r(&seed);
                    }
                }
                poDS->RasterIO(GF_Write, 0, iY, nXSize, 1,
                               pabyLine, nXSize, 1,
                               GDT_Byte,
                               nBands, NULL,
                               0, 0, 0
#ifdef GDAL_COMPILATION
                               , NULL
#endif
                               );
            }
            VSIFree(pabyLine);
        }
        if( bMemDriver ) 
            poMEMDS = poDS;
        else
            GDALClose(poDS);
    }
    else
    {
        bCheck = FALSE;
    }
    CSLDestroy(papszOptions);
    papszOptions = NULL;
    
    Request* psGlobalRequestLast = NULL;

    for(i = 0; i < nThreads; i++ )
    {
        GDALDataset* poDS;
        // Since GDAL 2.0, the MEM driver is thread-safe, i.e. does not use the block
        // cache, but only for operations not involving resampling, which is
        // the case here
        if( poMEMDS ) 
            poDS = poMEMDS;
        else
        {
            poDS = (GDALDataset*)GDALOpen(pszDataset, GA_ReadOnly);
            if( poDS == NULL )
                exit(1);
        }
        if( bMigrate )
        {
            Resource* psResource = (Resource*)CPLMalloc(sizeof(Resource));
            psResource->poDS = poDS;
            int nBufferSize;
            if( eStrategy == STRATEGY_RANDOM )
                nBufferSize = CreateRandomStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            else if( eStrategy == STRATEGY_LINE )
                nBufferSize = CreateLineStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            else
                nBufferSize = CreateBlockStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            psResource->pBuffer = CPLMalloc(nBufferSize);
            PutResourceAtEnd(psResource);
        }
        else
        {
            ThreadDescription sThreadDescription;
            sThreadDescription.poDS = poDS;
            sThreadDescription.psRequestList = NULL;
            Request* psRequestLast = NULL;
            if( eStrategy == STRATEGY_RANDOM )
                sThreadDescription.nBufferSize = CreateRandomStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            else if( eStrategy == STRATEGY_LINE )
                sThreadDescription.nBufferSize = CreateLineStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            else
                sThreadDescription.nBufferSize = CreateBlockStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            asThreadDescription.push_back(sThreadDescription);
        }
    }

    if( bCreatedDataset && poMEMDS == NULL && bOnDisk )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        VSIUnlink(pszDataset);
        CPLPopErrorHandler();
    }
    
    if( bMigrate )
    {
        psLock = CPLCreateLock(LOCK_SPIN);
    }

    for(i = 0; i < nThreads; i++ )
    {
        CPLJoinableThread* pThread;
        if( bMigrate )
            pThread = CPLCreateJoinableThread(ThreadFuncWithMigration, NULL);
        else
            pThread = CPLCreateJoinableThread(ThreadFuncDedicatedDataset,
                                              &(asThreadDescription[i]));
        apsThreads.push_back(pThread);
    }
    for(i = 0; i < nThreads; i++ )
    {
        CPLJoinThread(apsThreads[i]);
        if( !bMigrate && poMEMDS == NULL )
            GDALClose(asThreadDescription[i].poDS);
    }
    while( psGlobalResourceList != NULL )
    {
        CPLFree( psGlobalResourceList->pBuffer);
        if( poMEMDS == NULL )
            GDALClose(psGlobalResourceList->poDS);
        Resource* psNext = psGlobalResourceList->psNext;
        CPLFree( psGlobalResourceList );
        psGlobalResourceList = psNext;
    }

    if( psLock )
    {
        CPLDestroyLock( psLock );
    }

    if( bCreatedDataset && poMEMDS == NULL  )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        VSIUnlink(pszDataset);
        CPLPopErrorHandler();
    }
    if( poMEMDS )
        GDALClose(poMEMDS);

    assert( GDALGetCacheUsed64() == 0 );

    GDALDestroyDriverManager();
    CSLDestroy( argv );

    return 0;
}
OGRErr OGRGeometryCollection::exportToWkt( char ** ppszDstText ) const

{
    char        **papszGeoms;
    int         iGeom, nCumulativeLength = 0;
    OGRErr      eErr;

    if( getNumGeometries() == 0 )
    {
        *ppszDstText = CPLStrdup("GEOMETRYCOLLECTION EMPTY");
        return OGRERR_NONE;
    }

/* -------------------------------------------------------------------- */
/*      Build a list of strings containing the stuff for each Geom.     */
/* -------------------------------------------------------------------- */
    papszGeoms = (char **) CPLCalloc(sizeof(char *),nGeomCount);

    for( iGeom = 0; iGeom < nGeomCount; iGeom++ )
    {
        eErr = papoGeoms[iGeom]->exportToWkt( &(papszGeoms[iGeom]) );
        if( eErr != OGRERR_NONE )
            goto error;

        nCumulativeLength += strlen(papszGeoms[iGeom]);
    }
    
/* -------------------------------------------------------------------- */
/*      Allocate the right amount of space for the aggregated string    */
/* -------------------------------------------------------------------- */
    *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nGeomCount + 23);

    if( *ppszDstText == NULL )
    {
        eErr = OGRERR_NOT_ENOUGH_MEMORY;
        goto error;
    }

/* -------------------------------------------------------------------- */
/*      Build up the string, freeing temporary strings as we go.        */
/* -------------------------------------------------------------------- */
    strcpy( *ppszDstText, getGeometryName() );
    strcat( *ppszDstText, " (" );
    nCumulativeLength = strlen(*ppszDstText);

    for( iGeom = 0; iGeom < nGeomCount; iGeom++ )
    {                                                           
        if( iGeom > 0 )
            (*ppszDstText)[nCumulativeLength++] = ',';
        
        int nGeomLength = strlen(papszGeoms[iGeom]);
        memcpy( *ppszDstText + nCumulativeLength, papszGeoms[iGeom], nGeomLength );
        nCumulativeLength += nGeomLength;
        VSIFree( papszGeoms[iGeom] );
    }

    (*ppszDstText)[nCumulativeLength++] = ')';
    (*ppszDstText)[nCumulativeLength] = '\0';

    CPLFree( papszGeoms );

    return OGRERR_NONE;

error:
    for( iGeom = 0; iGeom < nGeomCount; iGeom++ )
        CPLFree( papszGeoms[iGeom] );
    CPLFree( papszGeoms );
    return eErr;
}
Exemple #3
0
GDALDataset *GSAGDataset::CreateCopy( const char *pszFilename,
				      GDALDataset *poSrcDS,
				      int bStrict, char **papszOptions,
				      GDALProgressFunc pfnProgress,
				      void *pProgressData )
{
    if( pfnProgress == NULL )
	pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GSAG driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands > 1)
    {
	if( bStrict )
	{
	    CPLError( CE_Failure, CPLE_NotSupported,
		      "Unable to create copy, Golden Software ASCII Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software ASCII Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" );

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

    int          nXSize = poSrcDS->GetRasterXSize();
    int          nYSize = poSrcDS->GetRasterYSize();
    double	 adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    std::ostringstream ssHeader;
    ssHeader.precision( nFIELD_PRECISION );
    ssHeader.setf( std::ios::uppercase );

    ssHeader << "DSAA\x0D\x0A";

    ssHeader << nXSize << " " << nYSize << "\x0D\x0A";

    ssHeader << adfGeoTransform[0] + adfGeoTransform[1] / 2 << " "
	     << adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]
	     << "\x0D\x0A";

    ssHeader << adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3] << " "
	     << adfGeoTransform[3] + adfGeoTransform[5] / 2
	     << "\x0D\x0A";

    if( VSIFWriteL( (void *)ssHeader.str().c_str(), 1, ssHeader.str().length(),
		    fp ) != ssHeader.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

    /* Save the location and write placeholders for the min/max Z value */
    vsi_l_offset nRangeStart = VSIFTellL( fp );
    const char *szDummyRange = "0.0000000000001 0.0000000000001\x0D\x0A";
    size_t nDummyRangeLen = strlen( szDummyRange );
    if( VSIFWriteL( (void *)szDummyRange, 1, nDummyRangeLen,
		    fp ) != nDummyRangeLen )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to create copy, writing header failed.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    double *pdfData = (double *)VSIMalloc2( nXSize, sizeof( double ) );
    if( pdfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1);
    int bSrcHasNDValue;
    double dfSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double dfMin = DBL_MAX;
    double dfMax = -DBL_MAX;
    for( int iRow=0; iRow<nYSize; iRow++ )
    {
	CPLErr eErr = poSrcBand->RasterIO( GF_Read, 0, nYSize-iRow-1,
					   nXSize, 1, pdfData,
					   nXSize, 1, GDT_Float64, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; )
	{
	    for( int iCount=0;
		 iCount<10 && iCol<nXSize;
		 iCount++, iCol++ )
	    {
		double dfValue = pdfData[iCol];

		if( bSrcHasNDValue && AlmostEqual( dfValue, dfSrcNoDataValue ) )
		{
		    dfValue = dfNODATA_VALUE;
		}
		else
		{
		    if( dfValue > dfMax )
			dfMax = dfValue;

		    if( dfValue < dfMin )
			dfMin = dfValue;
		}

		std::ostringstream ssOut;
		ssOut.precision(nFIELD_PRECISION);
		ssOut.setf( std::ios::uppercase );
		ssOut << dfValue << " ";
		CPLString sOut = ssOut.str();

		if( VSIFWriteL( sOut.c_str(), 1, sOut.length(), fp )
		    != sOut.length() )
		{
		    VSIFCloseL( fp );
		    VSIFree( pdfData );
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write grid cell.  Disk full?\n" );
		    return NULL;
		}
	    }

	    if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	    {
		VSIFCloseL( fp );
		VSIFree( pdfData );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to finish write of grid line. Disk full?\n" );
		return NULL;
	    }
	}

	if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to finish write of grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(iRow + 1)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pdfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pdfData );

    /* write out the min and max values */
    std::ostringstream ssRange;
    ssRange.precision( nFIELD_PRECISION );
    ssRange.setf( std::ios::uppercase );
    ssRange << dfMin << " " << dfMax << "\x0D\x0A";
    if( ssRange.str().length() != nDummyRangeLen )
    {
	int nShiftSize = ssRange.str().length() - nDummyRangeLen;
	if( ShiftFileContents( fp, nRangeStart + nDummyRangeLen,
			       nShiftSize, "\x0D\x0A" ) != CE_None )
	{
	    VSIFCloseL( fp );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to shift file contents.\n" );
	    return NULL;
	}
    }

    if( VSIFSeekL( fp, nRangeStart, SEEK_SET ) != 0 )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of grid file copy.\n" );
	return NULL;
    }

    if( VSIFWriteL( (void *)ssRange.str().c_str(), 1, ssRange.str().length(),
		    fp ) != ssRange.str().length() )
    {
	VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_FileIO,
                  "Unable to write range information.\n" );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }
    return poDS;
}
GDALDataset *GSBGDataset::CreateCopy( const char *pszFilename,
				      GDALDataset *poSrcDS,
				      int bStrict, char **papszOptions,
				      GDALProgressFunc pfnProgress,
				      void *pProgressData )
{
    if( pfnProgress == NULL )
	pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GSBG driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands > 1)
    {
	if( bStrict )
	{
	    CPLError( CE_Failure, CPLE_NotSupported,
		      "Unable to create copy, Golden Software Binary Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software Binary Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    if( poSrcBand->GetXSize() > SHRT_MAX
	|| poSrcBand->GetYSize() > SHRT_MAX )
    {
	CPLError( CE_Failure, CPLE_IllegalArg,
		  "Unable to create grid, Golden Software Binary Grid format "
		  "only supports sizes up to %dx%d.  %dx%d not supported.\n",
		  SHRT_MAX, SHRT_MAX,
		  poSrcBand->GetXSize(), poSrcBand->GetYSize() );

	return NULL;
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE    *fp = VSIFOpenL( pszFilename, "w+b" );

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

    GInt16  nXSize = (GInt16) poSrcBand->GetXSize();
    GInt16  nYSize = (GInt16) poSrcBand->GetYSize();
    double  adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2;
    double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0];
    double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3];
    double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2;
    CPLErr eErr = WriteHeader( fp, nXSize, nYSize,
			       dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) );
    if( pfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    int     bSrcHasNDValue;
    float   fSrcNoDataValue = (float) poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double  dfMinZ = DBL_MAX;
    double  dfMaxZ = -DBL_MAX;
    for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- )
    {
	eErr = poSrcBand->RasterIO( GF_Read, 0, iRow,
				    nXSize, 1, pfData,
				    nXSize, 1, GDT_Float32, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; iCol++ )
	{
	    if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue )
	    {
		pfData[iCol] = fNODATA_VALUE;
	    }
	    else
	    {
		if( pfData[iCol] > dfMaxZ )
		    dfMaxZ = pfData[iCol];

		if( pfData[iCol] < dfMinZ )
		    dfMinZ = pfData[iCol];
	    }

	    CPL_LSBPTR32( pfData+iCol );
	}

	if( VSIFWriteL( (void *)pfData, 4, nXSize,
			fp ) != static_cast<unsigned>(nXSize) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(nYSize - iRow)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pfData );

    /* write out the min and max values */
    eErr = WriteHeader( fp, nXSize, nYSize,
			dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDS = (GDALPamDataset *)GDALOpen( pszFilename,
                                                GA_Update );
    if (poDS)
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
    }
    return poDS;
}
GDALDataset *
RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                       int bStrict, char ** papszOptions, 
                       GDALProgressFunc pfnProgress, void * pProgressData )
{
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0");
        return NULL;
    }
    
    const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
    GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
    if ( hTileDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
        return NULL;
    }
    
    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
        return NULL;
    }   

    int nXSize = GDALGetRasterXSize(poSrcDS);
    int nYSize = GDALGetRasterYSize(poSrcDS);
    
    double adfGeoTransform[6];
    if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None)
    {
        adfGeoTransform[0] = 0;
        adfGeoTransform[1] = 1;
        adfGeoTransform[2] = 0;
        adfGeoTransform[3] = 0;
        adfGeoTransform[4] = 0;
        adfGeoTransform[5] = -1;
    }
    else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms");
        return NULL;
    }

    int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
    int nBlockXSize, nBlockYSize;
    if (bTiled)
    {
        nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
        nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
        if (nBlockXSize < 64) nBlockXSize = 64;
        else if (nBlockXSize > 4096)  nBlockXSize = 4096;
        if (nBlockYSize < 64) nBlockYSize = 64;
        else if (nBlockYSize > 4096)  nBlockYSize = 4096;
    }
    else
    {
        nBlockXSize = nXSize;
        nBlockYSize = nYSize;
    }
    
/* -------------------------------------------------------------------- */
/*      Analyze arguments                                               */
/* -------------------------------------------------------------------- */
    
    CPLString osDBName;
    CPLString osTableName;
    VSIStatBuf sBuf;
    int bExists;

    /* Skip optionnal RASTERLITE: prefix */
    const char* pszFilenameWithoutPrefix = pszFilename;
    if (EQUALN(pszFilename, "RASTERLITE:", 11))
        pszFilenameWithoutPrefix += 11;
    
    char** papszTokens = CSLTokenizeStringComplex( 
                pszFilenameWithoutPrefix, ", ", FALSE, FALSE );
    int nTokens = CSLCount(papszTokens);
    if (nTokens == 0)
    {
        osDBName = pszFilenameWithoutPrefix;
        osTableName = CPLGetBasename(pszFilenameWithoutPrefix);
    }
    else
    {
        osDBName = papszTokens[0];
        
        int i;
        for(i=1;i<nTokens;i++)
        {
            if (EQUALN(papszTokens[i], "table=", 6))
                osTableName = papszTokens[i] + 6;
            else
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "Invalid option : %s", papszTokens[i]);
            }
        }
    }
    
    CSLDestroy(papszTokens);
    papszTokens = NULL;
    
    bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0);

    if (osTableName.size() == 0)
    {
        if (bExists)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Database already exists. Explicit table name must be specified");
            return NULL;
        }
        osTableName = CPLGetBasename(osDBName.c_str());
    }    
    
    CPLString osRasterLayer;
    osRasterLayer.Printf("%s_rasters", osTableName.c_str());
    
    CPLString osMetatadataLayer;
    osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());

/* -------------------------------------------------------------------- */
/*      Create or open the SQLite DB                                    */
/* -------------------------------------------------------------------- */
    
    if (OGRGetDriverCount() == 0)
        OGRRegisterAll();
        
    OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite");
    if (hSQLiteDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver");
        return NULL;
    }   
    
    OGRDataSourceH hDS;
    
    CPLString osOldVal =
        CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
    CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
    if (!bExists)
    {
        char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES");
        hDS = OGR_Dr_CreateDataSource(hSQLiteDriver,
                                      osDBName.c_str(), papszOGROptions);
        CSLDestroy(papszOGROptions);
    }
    else
    {
        hDS = OGROpen(osDBName.c_str(), TRUE, NULL);
    }
    CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
    
    if (hDS == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot load or create SQLite database");
        return NULL;
    }

    CPLString osSQL;
    
/* -------------------------------------------------------------------- */
/*      Get the SRID for the SRS                                        */
/* -------------------------------------------------------------------- */
    int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef());

/* -------------------------------------------------------------------- */
/*      Create or wipe existing tables                                  */
/* -------------------------------------------------------------------- */
    int bWipeExistingData =
        CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO"));
        
    hDS = RasterliteCreateTables(hDS, osTableName.c_str(),
                                 nSRSId, bWipeExistingData);
    if (hDS == NULL)
        return NULL;

    OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
    OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
    if (hRasterLayer == NULL || hMetadataLayer == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot find metadata and/or raster tables");
        OGRReleaseDataSource(hDS);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check if there is overlapping data and warn the user            */
/* -------------------------------------------------------------------- */
    double minx = adfGeoTransform[0];
    double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1];
    double maxy = adfGeoTransform[3];
    double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5];
    
    osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" "
                 "WHERE rowid IN "
                 "(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
                  "WHERE xmin < %.15f AND xmax > %.15f "
                  "AND ymin < %.15f  AND ymax > %.15f) "
                 "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                 "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
                  osMetatadataLayer.c_str(),
                  osTableName.c_str(),
                  maxx, minx, maxy, miny,
                  adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15,
                  - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15);
    
    int nOverlappingGeoms = 0;
    OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hCountLyr)
    {
        OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr);
        if (hFeat)
        {
            nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0);
            OGR_F_Destroy(hFeat);
        }
        OGR_DS_ReleaseResultSet(hDS, hCountLyr);
    }
    
    if (nOverlappingGeoms != 0)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Raster tiles already exist in the %s table within "
                 "the extent of the data to be inserted in",
                 osTableName.c_str());
    }
   
/* -------------------------------------------------------------------- */
/*      Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */
    int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;

    GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
    GByte* pabyMEMDSBuffer =
        (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
    if (pabyMEMDSBuffer == NULL)
    {
        OGRReleaseDataSource(hDS);
        return NULL;
    }
    
    CPLString osTempFileName;
    osTempFileName.Printf("/vsimem/%p", hDS);
    
    int nTileId = 0;
    int nBlocks = 0;
    int nTotalBlocks = nXBlocks * nYBlocks;

    char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);
    
    OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
    
    CPLErr eErr = CE_None;
    int nBlockXOff, nBlockYOff;
    for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
    {
        for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
        {
/* -------------------------------------------------------------------- */
/*      Create in-memory tile                                           */
/* -------------------------------------------------------------------- */
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nXSize)
                nReqXSize = nXSize - nBlockXOff * nBlockXSize;
            if ((nBlockYOff+1) * nBlockYSize > nYSize)
                nReqYSize = nYSize - nBlockYOff * nBlockYSize;

            eErr = poSrcDS->RasterIO(GF_Read,
                                     nBlockXOff * nBlockXSize,
                                     nBlockYOff * nBlockYSize,
                                     nReqXSize, nReqYSize,
                                     pabyMEMDSBuffer, nReqXSize, nReqYSize,
                                     eDataType, nBands, NULL,
                                     0, 0, 0);
            if (eErr != CE_None)
            {
                break;
            }
            
            GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
                                              nReqXSize, nReqYSize, 0, 
                                              eDataType, NULL);
            if (hMemDS == NULL)
            {
                eErr = CE_Failure;
                break;
            }
            
            int iBand;
            for(iBand = 0; iBand < nBands; iBand ++)
            {
                char** papszMEMDSOptions = NULL;
                char szTmp[64];
                memset(szTmp, 0, sizeof(szTmp));
                CPLPrintPointer(szTmp,
                                pabyMEMDSBuffer + iBand * nDataTypeSize *
                                nReqXSize * nReqYSize, sizeof(szTmp));
                papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp);
                GDALAddBand(hMemDS, eDataType, papszMEMDSOptions);
                CSLDestroy(papszMEMDSOptions);
            }
            
            GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
                                        osTempFileName.c_str(), hMemDS, FALSE,
                                        papszTileDriverOptions, NULL, NULL);

            GDALClose(hMemDS);
            if (hOutDS)
                GDALClose(hOutDS);
            else
            {
                eErr = CE_Failure;
                break;
            }

/* -------------------------------------------------------------------- */
/*      Insert new entry into raster table                              */
/* -------------------------------------------------------------------- */

            vsi_l_offset nDataLength;
            GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
                                                   &nDataLength, FALSE);

            OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
            OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
            
            OGR_L_CreateFeature(hRasterLayer, hFeat);
            /* Query raster ID to set it as the ID of the associated metadata */
            int nRasterID = (int)OGR_F_GetFID(hFeat);
            
            OGR_F_Destroy(hFeat);
            
            VSIUnlink(osTempFileName.c_str());
            
/* -------------------------------------------------------------------- */
/*      Insert new entry into metadata table                            */
/* -------------------------------------------------------------------- */
            
            hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
            OGR_F_SetFID(hFeat, nRasterID);
            OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS));
            OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
            OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
            OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
            OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]);
            OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]);
            
            minx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff) * adfGeoTransform[1];
            maxx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1];
            maxy = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff) * adfGeoTransform[5];
            miny = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5];
            
            OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
            OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
            
            OGR_F_SetGeometryDirectly(hFeat, hRectangle);
            
            OGR_L_CreateFeature(hMetadataLayer, hFeat);
            OGR_F_Destroy(hFeat);
            
            nBlocks++;
            if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
                                            NULL, pProgressData))
                eErr = CE_Failure;
        }
    }
    
    if (eErr == CE_None)
        OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
    else
        OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
    
    CSLDestroy(papszTileDriverOptions);
    
    VSIFree(pabyMEMDSBuffer);
    
    OGRReleaseDataSource(hDS);
        
    return (GDALDataset*) GDALOpen(pszFilename, GA_Update);
}
Exemple #6
0
CPLErr GSAGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
				    void * pImage )

{
    if( eAccess == GA_ReadOnly )
    {
	CPLError( CE_Failure, CPLE_NoWriteAccess,
		  "Unable to write block, dataset opened read only.\n" );
	return CE_Failure;
    }

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

    GSAGDataset *poGDS = (GSAGDataset *)poDS;
    assert( poGDS != NULL );

    if( padfRowMinZ == NULL || padfRowMaxZ == NULL
	|| nMinZRow < 0 || nMaxZRow < 0 )
    {
	padfRowMinZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) );
	if( padfRowMinZ == NULL )
	{
	    CPLError( CE_Failure, CPLE_OutOfMemory,
		      "Unable to allocate space for row minimums array.\n" );
	    return CE_Failure;
	}

	padfRowMaxZ = (double *)VSIMalloc2( nRasterYSize,sizeof(double) );
	if( padfRowMaxZ == NULL )
	{
	    VSIFree( padfRowMinZ );
	    padfRowMinZ = NULL;
	    CPLError( CE_Failure, CPLE_OutOfMemory,
		      "Unable to allocate space for row maximums array.\n" );
	    return CE_Failure;
	}

	CPLErr eErr = ScanForMinMaxZ();
	if( eErr != CE_None )
	    return eErr;
    }

    if( panLineOffset[nBlockYOff+1] == 0 )
	IReadBlock( nBlockXOff, nBlockYOff, NULL );

    if( panLineOffset[nBlockYOff+1] == 0 || panLineOffset[nBlockYOff] == 0 )
	return CE_Failure;

    std::ostringstream ssOutBuf;
    ssOutBuf.precision( GSAGDataset::nFIELD_PRECISION );
    ssOutBuf.setf( std::ios::uppercase );

    double *pdfImage = (double *)pImage;
    padfRowMinZ[nBlockYOff] = DBL_MAX;
    padfRowMaxZ[nBlockYOff] = -DBL_MAX;
    for( int iCell=0; iCell<nBlockXSize; )
    {
	for( int iCol=0; iCol<10 && iCell<nBlockXSize; iCol++, iCell++ )
	{
	    if( AlmostEqual( pdfImage[iCell], GSAGDataset::dfNODATA_VALUE ) )
	    {
		if( pdfImage[iCell] < padfRowMinZ[nBlockYOff] )
		    padfRowMinZ[nBlockYOff] = pdfImage[iCell];

		if( pdfImage[iCell] > padfRowMaxZ[nBlockYOff] )
		    padfRowMaxZ[nBlockYOff] = pdfImage[iCell];
	    }

	    ssOutBuf << pdfImage[iCell] << " ";
	}
	ssOutBuf << poGDS->szEOL;
    }
    ssOutBuf << poGDS->szEOL;

    CPLString sOut = ssOutBuf.str();
    if( sOut.length() != panLineOffset[nBlockYOff+1]-panLineOffset[nBlockYOff] )
    {
	int nShiftSize = (int) (sOut.length() - (panLineOffset[nBlockYOff+1]
                                                 - panLineOffset[nBlockYOff]));
	if( nBlockYOff != poGDS->nRasterYSize
	    && GSAGDataset::ShiftFileContents( poGDS->fp,
					       panLineOffset[nBlockYOff+1],
					       nShiftSize,
					       poGDS->szEOL ) != CE_None )
	{
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Failure writing block, "
		      "unable to shift file contents.\n" );
	    return CE_Failure;
	}

	for( size_t iLine=nBlockYOff+1;
	     iLine < static_cast<unsigned>(poGDS->nRasterYSize+1)
		&& panLineOffset[iLine] != 0; iLine++ )
	    panLineOffset[iLine] += nShiftSize;
    }

    if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 )
    {
	CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to grid line.\n" );
	return CE_Failure;
    }

    if( VSIFWriteL( sOut.c_str(), 1, sOut.length(),
		    poGDS->fp ) != sOut.length() )
    {
	CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid block.\n" );
	return CE_Failure;
    }

    /* Update header as needed */
    bool bHeaderNeedsUpdate = false;
    if( nMinZRow == nBlockYOff && padfRowMinZ[nBlockYOff] > dfMinZ )
    {
	double dfNewMinZ = -DBL_MAX;
	for( int iRow=0; iRow<nRasterYSize; iRow++ )
	{
	    if( padfRowMinZ[iRow] < dfNewMinZ )
	    {
		dfNewMinZ = padfRowMinZ[iRow];
		nMinZRow = iRow;
	    }
	}

	if( dfNewMinZ != dfMinZ )
	{
	    dfMinZ = dfNewMinZ;
	    bHeaderNeedsUpdate = true;
	}
    }

    if( nMaxZRow == nBlockYOff && padfRowMaxZ[nBlockYOff] < dfMaxZ )
    {
	double dfNewMaxZ = -DBL_MAX;
	for( int iRow=0; iRow<nRasterYSize; iRow++ )
	{
	    if( padfRowMaxZ[iRow] > dfNewMaxZ )
	    {
		dfNewMaxZ = padfRowMaxZ[iRow];
		nMaxZRow = iRow;
	    }
	}

	if( dfNewMaxZ != dfMaxZ )
	{
	    dfMaxZ = dfNewMaxZ;
	    bHeaderNeedsUpdate = true;
	}
    }

    if( padfRowMinZ[nBlockYOff] < dfMinZ || padfRowMaxZ[nBlockYOff] > dfMaxZ )
    {
	if( padfRowMinZ[nBlockYOff] < dfMinZ )
	{
	    dfMinZ = padfRowMinZ[nBlockYOff];
	    nMinZRow = nBlockYOff;
	}

	if( padfRowMaxZ[nBlockYOff] > dfMaxZ )
	{
	    dfMaxZ = padfRowMaxZ[nBlockYOff];
	    nMaxZRow = nBlockYOff;
	}

	bHeaderNeedsUpdate = true;
    }

    if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ )
    {
	CPLErr eErr = poGDS->UpdateHeader();
	return eErr;
    }

    return CE_None;
}
CPLErr GSBGRasterBand::ScanForMinMaxZ()

{
    float *pafRowVals = (float *)VSIMalloc2( nRasterXSize, 4 );

    if( pafRowVals == NULL )
    {
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to allocate row buffer to scan grid file.\n" );
	return CE_Failure;
    }

    double dfNewMinZ = DBL_MAX;
    double dfNewMaxZ = -DBL_MAX;
    int nNewMinZRow = 0;
    int nNewMaxZRow = 0;

    /* Since we have to scan, lets calc. statistics too */
    double dfSum = 0.0;
    double dfSum2 = 0.0;
    unsigned long nValuesRead = 0;
    for( int iRow=0; iRow<nRasterYSize; iRow++ )
    {
	CPLErr eErr = IReadBlock( 0, iRow, pafRowVals );
	if( eErr != CE_None )
	{
	    VSIFree( pafRowVals );
	    return CE_Failure;
	}

	pafRowMinZ[iRow] = FLT_MAX;
	pafRowMaxZ[iRow] = -FLT_MAX;
	for( int iCol=0; iCol<nRasterXSize; iCol++ )
	{
	    if( pafRowVals[iCol] == GSBGDataset::fNODATA_VALUE )
		continue;

	    if( pafRowVals[iCol] < pafRowMinZ[iRow] )
		pafRowMinZ[iRow] = pafRowVals[iCol];

	    if( pafRowVals[iCol] > pafRowMinZ[iRow] )
		pafRowMaxZ[iRow] = pafRowVals[iCol];

	    dfSum += pafRowVals[iCol];
	    dfSum2 += pafRowVals[iCol] * pafRowVals[iCol];
	    nValuesRead++;
	}

	if( pafRowMinZ[iRow] < dfNewMinZ )
	{
	    dfNewMinZ = pafRowMinZ[iRow];
	    nNewMinZRow = iRow;
	}

	if( pafRowMaxZ[iRow] > dfNewMaxZ )
	{
	    dfNewMaxZ = pafRowMaxZ[iRow];
	    nNewMaxZRow = iRow;
	}
    }

    VSIFree( pafRowVals );

    if( nValuesRead == 0 )
    {
	dfMinZ = 0.0;
	dfMaxZ = 0.0;
	nMinZRow = 0;
	nMaxZRow = 0;
	return CE_None;
    }

    dfMinZ = dfNewMinZ;
    dfMaxZ = dfNewMaxZ;
    nMinZRow = nNewMinZRow;
    nMaxZRow = nNewMaxZRow;

    double dfMean = dfSum / nValuesRead;
    double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean));
    SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev );

    return CE_None;
}
GDALDataset *GSBGDataset::CreateCopy( const char *pszFilename,
				      GDALDataset *poSrcDS,
				      int bStrict, char **papszOptions,
				      GDALProgressFunc pfnProgress,
				      void *pProgressData )
{
    if( pfnProgress == NULL )
	pfnProgress = GDALDummyProgress;

    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "GSBG driver does not support source dataset with zero band.\n");
        return NULL;
    }
    else if (nBands > 1)
    {
	if( bStrict )
	{
	    CPLError( CE_Failure, CPLE_NotSupported,
		      "Unable to create copy, Golden Software Binary Grid "
		      "format only supports one raster band.\n" );
	    return NULL;
	}
	else
	    CPLError( CE_Warning, CPLE_NotSupported,
		      "Golden Software Binary Grid format only supports one "
		      "raster band, first band will be copied.\n" );
    }

    GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 );
    if( poSrcBand->GetXSize() > SHRT_MAX
	|| poSrcBand->GetYSize() > SHRT_MAX )
    {
	CPLError( CE_Failure, CPLE_IllegalArg,
		  "Unable to create grid, Golden Software Binary Grid format "
		  "only supports sizes up to %dx%d.  %dx%d not supported.\n",
		  SHRT_MAX, SHRT_MAX,
		  poSrcBand->GetXSize(), poSrcBand->GetYSize() );

	return NULL;
    }

    if( !pfnProgress( 0.0, NULL, pProgressData ) )
    {
        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" );
        return NULL;
    }

    VSILFILE    *fp = VSIFOpenL( pszFilename, "w+b" );

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

    GInt16  nXSize = poSrcBand->GetXSize();
    GInt16  nYSize = poSrcBand->GetYSize();
    double  adfGeoTransform[6];

    poSrcDS->GetGeoTransform( adfGeoTransform );

    double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2;
    double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0];
    double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3];
    double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2;
    CPLErr eErr = WriteHeader( fp, nXSize, nYSize,
			       dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Copy band data.							*/
/* -------------------------------------------------------------------- */
    float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) );
    if( pfData == NULL )
    {
	VSIFCloseL( fp );
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to create copy, unable to allocate line buffer.\n" );
	return NULL;
    }

    int     bSrcHasNDValue;
    float   fSrcNoDataValue = poSrcBand->GetNoDataValue( &bSrcHasNDValue );
    double  dfMinZ = DBL_MAX;
    double  dfMaxZ = -DBL_MAX;
    for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- )
    {
	eErr = poSrcBand->RasterIO( GF_Read, 0, iRow,
				    nXSize, 1, pfData,
				    nXSize, 1, GDT_Float32, 0, 0 );

	if( eErr != CE_None )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    return NULL;
	}

	for( int iCol=0; iCol<nXSize; iCol++ )
	{
	    if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue )
	    {
		pfData[iCol] = fNODATA_VALUE;
	    }
	    else
	    {
		if( pfData[iCol] > dfMaxZ )
		    dfMaxZ = pfData[iCol];

		if( pfData[iCol] < dfMinZ )
		    dfMinZ = pfData[iCol];
	    }

	    CPL_LSBPTR32( pfData+iCol );
	}

	if( VSIFWriteL( (void *)pfData, 4, nXSize,
			fp ) != static_cast<unsigned>(nXSize) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write grid row. Disk full?\n" );
	    return NULL;
	}

	if( !pfnProgress( static_cast<double>(iRow)/nYSize,
			  NULL, pProgressData ) )
	{
	    VSIFCloseL( fp );
	    VSIFree( pfData );
	    CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
	    return NULL;
	}
    }

    VSIFree( pfData );

    /* write out the min and max values */
    eErr = WriteHeader( fp, nXSize, nYSize,
			dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ );

    if( eErr != CE_None )
    {
	VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

    GDALPamDataset *poDstDS = (GDALPamDataset *)GDALOpen( pszFilename,
							  GA_Update );
    if( poDstDS == NULL )
    {
	VSIUnlink( pszFilename );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to open copy of dataset.\n" );
	return NULL;
    }
    else if( dynamic_cast<GSBGDataset *>(poDstDS) == NULL )
    {
	VSIUnlink( pszFilename );
	delete poDstDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Copy dataset not opened as Golden Surfer Binary Grid!?\n" );
	return NULL;
    }

    GDALRasterBand *poDstBand = poSrcDS->GetRasterBand(1);
    if( poDstBand == NULL )
    {
	VSIUnlink( pszFilename );
	delete poDstDS;
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to open copy of raster band?\n" );
	return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Attempt to copy metadata.					*/
/* -------------------------------------------------------------------- */
    if( !bStrict )
	CPLPushErrorHandler( CPLQuietErrorHandler );

    /* non-zero transform 2 or 4 or negative 1 or 5  not supported natively */
    /*if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0
	|| adfGeoTransform[1] < 0.0 || adfGeoTransform[5] < 0.0 )
	poDstDS->GDALPamDataset::SetGeoTransform( adfGeoTransform );*/

    const char *szProjectionRef = poSrcDS->GetProjectionRef();
    if( *szProjectionRef != '\0' )
	poDstDS->SetProjection( szProjectionRef );

    char **pszMetadata = poSrcDS->GetMetadata();
    if( pszMetadata != NULL )
	poDstDS->SetMetadata( pszMetadata );

    /* FIXME:  Should the dataset description be copied as well, or is it
     *         always the file name? */
    poDstBand->SetDescription( poSrcBand->GetDescription() );

    int bSuccess;
    double dfOffset = poSrcBand->GetOffset( &bSuccess );
    if( bSuccess && dfOffset != 0.0 )
	poDstBand->SetOffset( dfOffset );

    double dfScale = poSrcBand->GetScale( &bSuccess );
    if( bSuccess && dfScale != 1.0 )
	poDstBand->SetScale( dfScale );

    GDALColorInterp oColorInterp = poSrcBand->GetColorInterpretation();
    if( oColorInterp != GCI_Undefined )
        poDstBand->SetColorInterpretation( oColorInterp );

    char **pszCatNames = poSrcBand->GetCategoryNames();
    if( pszCatNames != NULL)
	poDstBand->SetCategoryNames( pszCatNames );

    GDALColorTable *poColorTable = poSrcBand->GetColorTable();
    if( poColorTable != NULL )
	poDstBand->SetColorTable( poColorTable );

    if( !bStrict )
	CPLPopErrorHandler();

    return poDstDS;
}
Exemple #9
0
JDEMRasterBand::~JDEMRasterBand()
{
    VSIFree(pszRecord);
}
Exemple #10
0
int VSIIngestFile( VSILFILE* fp,
                   const char* pszFilename,
                   GByte** ppabyRet,
                   vsi_l_offset* pnSize,
                   GIntBig nMaxSize)
{
    vsi_l_offset nDataLen = 0;
    int bFreeFP = FALSE;

    if( fp == NULL && pszFilename == NULL )
        return FALSE;
    if( ppabyRet == NULL )
        return FALSE;

    *ppabyRet = NULL;
    if( pnSize != NULL )
        *pnSize = 0;

    if( NULL == fp )
    {
        fp = VSIFOpenL( pszFilename, "rb" );
        if( NULL == fp )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Cannot open file '%s'", pszFilename );
            return FALSE;
        }
        bFreeFP = TRUE;
    }
    else
        VSIFSeekL(fp, 0, SEEK_SET);

    if( pszFilename == NULL ||
        strcmp(pszFilename, "/vsistdin/") == 0 )
    {
        vsi_l_offset nDataAlloc = 0;
        VSIFSeekL( fp, 0, SEEK_SET );
        while(TRUE)
        {
            if( nDataLen + 8192 + 1 > nDataAlloc )
            {
                nDataAlloc = (nDataAlloc * 4) / 3 + 8192 + 1;
                if( nDataAlloc > (vsi_l_offset)(size_t)nDataAlloc )
                {
                    CPLError( CE_Failure, CPLE_AppDefined,
                              "Input file too large to be opened" );
                    VSIFree( *ppabyRet );
                    *ppabyRet = NULL;
                    if( bFreeFP )
                        VSIFCloseL( fp );
                    return FALSE;
                }
                GByte* pabyNew = (GByte*)VSIRealloc(*ppabyRet, (size_t)nDataAlloc);
                if( pabyNew == NULL )
                {
                    CPLError( CE_Failure, CPLE_OutOfMemory,
                              "Cannot allocated " CPL_FRMT_GIB " bytes",
                              nDataAlloc );
                    VSIFree( *ppabyRet );
                    *ppabyRet = NULL;
                    if( bFreeFP )
                        VSIFCloseL( fp );
                    return FALSE;
                }
                *ppabyRet = pabyNew;
            }
            int nRead = (int)VSIFReadL( *ppabyRet + nDataLen, 1, 8192, fp );
            nDataLen += nRead;

            if ( nMaxSize >= 0 && nDataLen > (vsi_l_offset)nMaxSize )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                              "Input file too large to be opened" );
                VSIFree( *ppabyRet );
                *ppabyRet = NULL;
                if( pnSize != NULL )
                    *pnSize = 0;
                if( bFreeFP )
                    VSIFCloseL( fp );
                return FALSE;
            }

            if( pnSize != NULL )
                *pnSize += nRead;
            (*ppabyRet)[nDataLen] = '\0';
            if( nRead == 0 )
                break;
        }
    }
    else
    {
        VSIFSeekL( fp, 0, SEEK_END );
        nDataLen = VSIFTellL( fp );

        // With "large" VSI I/O API we can read data chunks larger than VSIMalloc
        // could allocate. Catch it here.
        if ( nDataLen > (vsi_l_offset)(size_t)nDataLen ||
             (nMaxSize >= 0 && nDataLen > (vsi_l_offset)nMaxSize) )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Input file too large to be opened" );
            if( bFreeFP )
                VSIFCloseL( fp );
            return FALSE;
        }

        VSIFSeekL( fp, 0, SEEK_SET );

        *ppabyRet = (GByte*)VSIMalloc((size_t)(nDataLen + 1));
        if( NULL == *ppabyRet )
        {
            CPLError( CE_Failure, CPLE_OutOfMemory,
                      "Cannot allocated " CPL_FRMT_GIB " bytes",
                      nDataLen + 1 );
            if( bFreeFP )
                VSIFCloseL( fp );
            return FALSE;
        }

        (*ppabyRet)[nDataLen] = '\0';
        if( ( nDataLen != VSIFReadL( *ppabyRet, 1, (size_t)nDataLen, fp ) ) )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Cannot read " CPL_FRMT_GIB " bytes",
                      nDataLen );
            VSIFree( *ppabyRet );
            *ppabyRet = NULL;
            if( bFreeFP )
                VSIFCloseL( fp );
            return FALSE;
        }
        if( pnSize != NULL )
            *pnSize = nDataLen;
    }
    if( bFreeFP )
        VSIFCloseL( fp );
    return TRUE;
}
int NASReader::LoadClasses( const char *pszFile )

{
    // Add logic later to determine reasonable default schema file. 
    if( pszFile == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Load the raw XML file.                                          */
/* -------------------------------------------------------------------- */
    FILE       *fp;
    int         nLength;
    char        *pszWholeText;

    fp = VSIFOpen( pszFile, "rb" );

    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to open file %s.", pszFile );
        return FALSE;
    }

    VSIFSeek( fp, 0, SEEK_END );
    nLength = VSIFTell( fp );
    VSIFSeek( fp, 0, SEEK_SET );

    pszWholeText = (char *) VSIMalloc(nLength+1);
    if( pszWholeText == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Failed to allocate %d byte buffer for %s,\n"
                  "is this really a GMLFeatureClassList file?",
                  nLength, pszFile );
        VSIFClose( fp );
        return FALSE;
    }
    
    if( VSIFRead( pszWholeText, nLength, 1, fp ) != 1 )
    {
        VSIFree( pszWholeText );
        VSIFClose( fp );
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Read failed on %s.", pszFile );
        return FALSE;
    }
    pszWholeText[nLength] = '\0';

    VSIFClose( fp );

    if( strstr( pszWholeText, "<GMLFeatureClassList>" ) == NULL )
    {
        VSIFree( pszWholeText );
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "File %s does not contain a GMLFeatureClassList tree.",
                  pszFile );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Convert to XML parse tree.                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRoot;

    psRoot = CPLParseXMLString( pszWholeText );
    VSIFree( pszWholeText );

    // We assume parser will report errors via CPL.
    if( psRoot == NULL )
        return FALSE;

    if( psRoot->eType != CXT_Element 
        || !EQUAL(psRoot->pszValue,"GMLFeatureClassList") )
    {
        CPLDestroyXMLNode(psRoot);
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "File %s is not a GMLFeatureClassList document.",
                  pszFile );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Extract feature classes for all definitions found.              */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psThis;

    for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext )
    {
        if( psThis->eType == CXT_Element 
            && EQUAL(psThis->pszValue,"GMLFeatureClass") )
        {
            GMLFeatureClass   *poClass;

            poClass = new GMLFeatureClass();

            if( !poClass->InitializeFromXML( psThis ) )
            {
                delete poClass;
                CPLDestroyXMLNode( psRoot );
                return FALSE;
            }

            poClass->SetSchemaLocked( TRUE );

            AddClass( poClass );
        }
    }

    CPLDestroyXMLNode( psRoot );
    
    SetClassListLocked( TRUE );

    return TRUE;
}
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);
            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);
            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))
            {
                unsigned int iPart;
                for(iPart = 0; iPart < nParts; iPart ++)
                {
                    unsigned int nNodes;
                    if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1)
                        return NULL;
                    CPL_LSBPTR32(&nNodes);
                    if (nNodes > nTotalNodes)
                        return NULL;
                    VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR);
                }
                nNextFID ++;
                continue;
            }

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

            unsigned int iPart;
            OGRPolygon* poGeom = new OGRPolygon();
            for(iPart = 0; iPart < nParts; iPart ++)
            {
                unsigned int nNodes;
                if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1)
                {
                    VSIFree(poRawPoints);
                    delete poGeom;
                    return NULL;
                }
                CPL_LSBPTR32(&nNodes);

                if (nNodes > nTotalNodes ||
                    (unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes)
                {
                    VSIFree(poRawPoints);
                    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);

            if (poSRS)
                poGeom->assignSpatialReference(poSRS);
            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetField(0, dfId);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetGeometryDirectly(poGeom);
            return poFeature;
        }
    }
}
void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle  const & extent, int width, int height )
{
  Q_UNUSED( bandNo );
  if ( !mInput || !mShader )
  {
    return 0;
  }

  QgsRasterInterface::DataType transparencyType = QgsRasterInterface::UnknownDataType;
  if ( mAlphaBand > 0 )
  {
    transparencyType = ( QgsRasterInterface::DataType )mInput->dataType( mAlphaBand );
  }

  void* transparencyData = 0;
  double currentOpacity = mOpacity;
  QgsRasterInterface::DataType rasterType = ( QgsRasterInterface::DataType )mInput->dataType( mBand );

  void* rasterData = mInput->block( mBand, extent, width, height );

  int red, green, blue;
  QRgb myDefaultColor = qRgba( 255, 255, 255, 0 );

  //rendering is faster without considering user-defined transparency
  bool hasTransparency = usesTransparency();

  if ( mAlphaBand > 0 && mAlphaBand != mBand )
  {
    transparencyData = mInput->block( mAlphaBand, extent, width, height );
  }
  else if ( mAlphaBand == mBand )
  {
    transparencyData = rasterData;
  }

  //create image
  QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
  QRgb* imageScanLine = 0;
  double val = 0;

  int currentRasterPos = 0;
  for ( int i = 0; i < height; ++i )
  {
    imageScanLine = ( QRgb* )( img.scanLine( i ) );
    for ( int j = 0; j < width; ++j )
    {
      val = readValue( rasterData, rasterType, currentRasterPos );
      if ( !mShader->shade( val, &red, &green, &blue ) )
      {
        imageScanLine[j] = myDefaultColor;
        ++currentRasterPos;
        continue;
      }

      if ( !hasTransparency )
      {
        imageScanLine[j] = qRgba( red, green, blue, 255 );
      }
      else
      {
        //opacity
        currentOpacity = mOpacity;
        if ( mRasterTransparency )
        {
          currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0;
        }
        if ( mAlphaBand > 0 )
        {
          currentOpacity *= ( readValue( transparencyData, transparencyType, currentRasterPos ) / 255.0 );
        }

        imageScanLine[j] = qRgba( currentOpacity * red, currentOpacity * green, currentOpacity * blue, currentOpacity * 255 );
      }
      ++currentRasterPos;
    }
  }

  VSIFree( rasterData );

  void * data = VSIMalloc( img.byteCount() );
  return memcpy( data, img.bits(), img.byteCount() );
}
GDALRescaledAlphaBand::~GDALRescaledAlphaBand()

{
    VSIFree(pTemp);
}
Exemple #15
0
SIGDEMRasterBand::~SIGDEMRasterBand() {
    SIGDEMRasterBand::FlushCache();
    VSIFree(pBlockBuffer);
}
CPLErr GDALRasterBlock::Internalize()

{
    CPLAssert( pData == NULL );

    void        *pNewData = NULL;

    // This call will initialize the hRBLock mutex. Other call places can
    // only be called if we have go through there.
    const GIntBig nCurCacheMax = GDALGetCacheMax64();

    // No risk of overflow as it is checked in GDALRasterBand::InitBlockInfo().
    const int nSizeInBytes = GetBlockSize();

/* -------------------------------------------------------------------- */
/*      Flush old blocks if we are nearing our memory limit.            */
/* -------------------------------------------------------------------- */
    bool bFirstIter = true;
    bool bLoopAgain = false;
    do
    {
        bLoopAgain = false;
        GDALRasterBlock* apoBlocksToFree[64] = { NULL };
        int nBlocksToFree = 0;
        {
            TAKE_LOCK;

            if( bFirstIter )
                nCacheUsed += nSizeInBytes;
            GDALRasterBlock *poTarget = poOldest;
            while( nCacheUsed > nCurCacheMax )
            {
                while( poTarget != NULL )
                {
                    if( CPLAtomicCompareAndExchange(
                            &(poTarget->nLockCount), 0, -1) )
                        break;
                    poTarget = poTarget->poPrevious;
                }

                if( poTarget != NULL )
                {
                    if( bSleepsForBockCacheDebug )
                        CPLSleep(CPLAtof(
                            CPLGetConfigOption(
                                "GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK",
                                "0")));

                    GDALRasterBlock* _poPrevious = poTarget->poPrevious;

                    poTarget->Detach_unlocked();
                    poTarget->GetBand()->UnreferenceBlock(poTarget);

                    apoBlocksToFree[nBlocksToFree++] = poTarget;
                    if( poTarget->GetDirty() )
                    {
                        // Only free one dirty block at a time so that
                        // other dirty blocks of other bands with the same
                        // coordinates can be found with TryGetLockedBlock()
                        bLoopAgain = nCacheUsed > nCurCacheMax;
                        break;
                    }
                    if( nBlocksToFree == 64 )
                    {
                        bLoopAgain = ( nCacheUsed > nCurCacheMax );
                        break;
                    }

                    poTarget = _poPrevious;
                }
                else
                {
                    break;
                }
            }

        /* ------------------------------------------------------------------ */
        /*      Add this block to the list.                                   */
        /* ------------------------------------------------------------------ */
            if( !bLoopAgain )
                Touch_unlocked();
        }

        bFirstIter = false;

        // Now free blocks we have detached and removed from their band.
        for( int i = 0; i < nBlocksToFree; ++i)
        {
            GDALRasterBlock * const poBlock = apoBlocksToFree[i];

            if( poBlock->GetDirty() )
            {
                CPLErr eErr = poBlock->Write();
                if( eErr != CE_None )
                {
                    // Save the error for later reporting.
                    poBlock->GetBand()->SetFlushBlockErr(eErr);
                }
            }

            // Try to recycle the data of an existing block.
            void* pDataBlock = poBlock->pData;
            if( pNewData == NULL && pDataBlock != NULL &&
                poBlock->GetBlockSize() == nSizeInBytes )
            {
                pNewData = pDataBlock;
            }
            else
            {
                VSIFree(poBlock->pData);
            }
            poBlock->pData = NULL;

            poBlock->GetBand()->AddBlockToFreeList(poBlock);
        }
    }
    while(bLoopAgain);

    if( pNewData == NULL )
    {
        pNewData = VSI_MALLOC_VERBOSE( nSizeInBytes );
        if( pNewData == NULL )
        {
            return( CE_Failure );
        }
    }

    pData = pNewData;

    return CE_None;
}
Exemple #17
0
CPLErr GSAGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
				   void * pImage )
{
    static size_t nMaxLineSize = 128;
    double *pdfImage = (double *)pImage;
    GSAGDataset *poGDS = (GSAGDataset *)poDS;

    assert( poGDS != NULL );

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

    if( panLineOffset[nBlockYOff] == 0 )
    {
        // Discover the last read block
        for ( int iFoundLine = nLastReadLine - 1; iFoundLine > nBlockYOff; iFoundLine--)
        {
            if( IReadBlock( nBlockXOff, iFoundLine, NULL) != CE_None )
                return CE_Failure;
        }
    }

    if( panLineOffset[nBlockYOff] == 0 )
        return CE_Failure;
    if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Can't seek to offset %ld to read grid row %d.",
                  (long) panLineOffset[nBlockYOff], nBlockYOff );
        return CE_Failure;
    }

    size_t nLineBufSize;
    char *szLineBuf = NULL;
    size_t nCharsRead;
    size_t nCharsExamined = 0;
    /* If we know the offsets, we can just read line directly */
    if( (nBlockYOff > 0) && ( panLineOffset[nBlockYOff-1] != 0 ) )
    {
	assert(panLineOffset[nBlockYOff-1] > panLineOffset[nBlockYOff]);
	nLineBufSize = (size_t) (panLineOffset[nBlockYOff-1]
                                 - panLineOffset[nBlockYOff] + 1);
    }
    else
    {
	nLineBufSize = nMaxLineSize;
    }

    szLineBuf = (char *)VSIMalloc( nLineBufSize );
    if( szLineBuf == NULL )
    {
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to read block, unable to allocate line buffer.\n" );
	return CE_Failure;
    }

    nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp );
    if( nCharsRead == 0 )
    {
	VSIFree( szLineBuf );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Can't read grid row %d at offset %ld.\n",
		  nBlockYOff, (long) panLineOffset[nBlockYOff] );
	return CE_Failure;
    }
    szLineBuf[nCharsRead] = '\0';

    char *szStart = szLineBuf;
    char *szEnd = szStart;
    for( int iCell=0; iCell<nBlockXSize; szStart = szEnd )
    {
	double dfValue = CPLStrtod( szStart, &szEnd );
	if( szStart == szEnd )
	{
	    /* No number found */

	    /* Check if this was an expected failure */
	    while( isspace( (unsigned char)*szStart ) )
		szStart++;

	    /* Found sign at end of input, seek back to re-read it */
	    if ( (*szStart == '-' || *szStart == '+') && *(szStart+1) == '\0' )
	    {
	    	if( VSIFSeekL( poGDS->fp, 
                               VSIFTellL( poGDS->fp)-1, 
                               SEEK_SET ) != 0 )
	    	{
		    VSIFree( szLineBuf );
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to seek in grid row %d "
			      "(offset %ld, seek %d).\n",
			      nBlockYOff, 
                              (long) VSIFTellL(poGDS->fp),
			      -1 );

		    return CE_Failure;
		}
	    }
	    else if( *szStart != '\0' )
	    {
		szEnd = szStart;
		while( !isspace( (unsigned char)*szEnd ) && *szEnd != '\0' )
		    szEnd++;
		char cOldEnd = *szEnd;
		*szEnd = '\0';

		CPLError( CE_Warning, CPLE_FileIO,
			  "Unexpected value in grid row %d (expected floating "
			  "point value, found \"%s\").\n",
			  nBlockYOff, szStart );

		*szEnd = cOldEnd;

		szEnd = szStart;
		while( !isdigit( *szEnd ) && *szEnd != '.' && *szEnd != '\0' )
		    szEnd++;

		continue;
	    }
	    else if( static_cast<size_t>(szStart - szLineBuf) != nCharsRead )
	    {
		CPLError( CE_Warning, CPLE_FileIO,
			  "Unexpected ASCII null-character in grid row %d at "
			  "offset %ld.\n", 
                          nBlockYOff, 
                          (long) (szStart - szLineBuf) );

		while( *szStart == '\0' &&
                       static_cast<size_t>(szStart - szLineBuf) < nCharsRead )
		    szStart++;

		szEnd = szStart;
		continue;
	    }

	    nCharsExamined += szStart - szLineBuf;
	    nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp );
	    if( nCharsRead == 0 )
	    {
		VSIFree( szLineBuf );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Can't read portion of grid row %d at offset %ld.",
			  nBlockYOff, (long) panLineOffset[nBlockYOff] );
		return CE_Failure;
	    }
	    szLineBuf[nCharsRead] = '\0';
	    szStart = szEnd = szLineBuf;
	    continue;
	}
	else if( *szEnd == '\0'
                 || (*szEnd == '.' && *(szEnd+1) == '\0')
                 || (*szEnd == '-' && *(szEnd+1) == '\0')
                 || (*szEnd == '+' && *(szEnd+1) == '\0')
                 || (*szEnd == 'E' && *(szEnd+1) == '\0')
                 || (*szEnd == 'E' && *(szEnd+1) == '-' && *(szEnd+2) == '\0')
                 || (*szEnd == 'E' && *(szEnd+1) == '+' && *(szEnd+2) == '\0')
                 || (*szEnd == 'e' && *(szEnd+1) == '\0')
                 || (*szEnd == 'e' && *(szEnd+1) == '-' && *(szEnd+2) == '\0')
                 || (*szEnd == 'e' && *(szEnd+1) == '+' && *(szEnd+2) == '\0'))
	{
	    /* Number was interrupted by a nul character */
	    while( *szEnd != '\0' )
		szEnd++;

	    if( static_cast<size_t>(szEnd - szLineBuf) != nCharsRead )
	    {
		CPLError( CE_Warning, CPLE_FileIO,
			  "Unexpected ASCII null-character in grid row %d at "
			  "offset %ld.\n", 
                          nBlockYOff, 
                          (long) (szStart - szLineBuf) );

		while( *szEnd == '\0' &&
		       static_cast<size_t>(szStart - szLineBuf) < nCharsRead )
		    szEnd++;

		continue;
	    }

	    /* End of buffer, could be interrupting a number */
	    if( VSIFSeekL( poGDS->fp, szStart - szEnd, SEEK_CUR ) != 0 )
	    {
		VSIFree( szLineBuf );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to seek in grid row %d (offset %ld, seek %d)"
			  ".\n", nBlockYOff, 
                          (long) VSIFTellL(poGDS->fp),
			  (int) (szStart - szEnd) );

		return CE_Failure;
	    }
	    nCharsExamined += szStart - szLineBuf;
	    nCharsRead = VSIFReadL( szLineBuf, 1, nLineBufSize - 1, poGDS->fp );
	    szLineBuf[nCharsRead] = '\0';

	    if( nCharsRead == 0 )
	    {
		VSIFree( szLineBuf );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Can't read portion of grid row %d at offset %ld.",
			  nBlockYOff, (long) panLineOffset[nBlockYOff] );
		return CE_Failure;
	    }
	    else if( nCharsRead > static_cast<size_t>(szEnd - szStart) )
	    {
		/* Read new data, this was not really the end */
		szEnd = szStart = szLineBuf;
		continue;
	    }

	    /* This is really the last value and has no tailing newline */
	    szStart = szLineBuf;
	    szEnd = szLineBuf + nCharsRead;
	}

	if( pdfImage != NULL )
	{
	    *(pdfImage+iCell) = dfValue;
	}

	iCell++;
    }

    while( *szEnd == ' ' )
	szEnd++;

    if( *szEnd != '\0' && *szEnd != poGDS->szEOL[0] )
	CPLDebug( "GSAG", "Grid row %d does not end with a newline.  "
                  "Possible skew.\n", nBlockYOff );

    while( isspace( (unsigned char)*szEnd ) )
	szEnd++;

    nCharsExamined += szEnd - szLineBuf;

    if( nCharsExamined >= nMaxLineSize )
	nMaxLineSize = nCharsExamined + 1;

    if( nBlockYOff > 0 )
        panLineOffset[nBlockYOff - 1] = 
            panLineOffset[nBlockYOff] + nCharsExamined;

    nLastReadLine = nBlockYOff;

    VSIFree( szLineBuf );

    return CE_None;
}
Exemple #18
0
void
_TIFFfree(tdata_t p)
{
    VSIFree( p );
}
GDALDataset *PALSARJaxaDataset::Open( GDALOpenInfo * poOpenInfo ) {
    /* Check that this actually is a JAXA PALSAR product */
    if ( !PALSARJaxaDataset::Identify(poOpenInfo) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The JAXAPALSAR driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

    PALSARJaxaDataset *poDS = new PALSARJaxaDataset();

    /* Get the suffix of the filename, we'll need this */
    char *pszSuffix = VSIStrdup( (char *)
                                 (CPLGetFilename( poOpenInfo->pszFilename ) + 3) );

    /* Try to read each of the polarizations */
    const size_t nImgFileLen =
        strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
        strlen( pszSuffix ) + 8;
    char *pszImgFile = (char *)CPLMalloc( nImgFileLen );

    int nBandNum = 1;

    /* HH */
    VSILFILE *fpHH;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-HH%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpHH = VSIFOpenL( pszImgFile, "rb" );
    if (fpHH != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 0, fpHH ) );
        nBandNum++;
    }

    /* HV */
    VSILFILE *fpHV;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-HV%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpHV = VSIFOpenL( pszImgFile, "rb" );
    if (fpHV != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 1, fpHV ) );
        nBandNum++;
    }

    /* VH */
    VSILFILE *fpVH;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-VH%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpVH = VSIFOpenL( pszImgFile, "rb" );
    if (fpVH != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 2, fpVH ) );
        nBandNum++;
    }

    /* VV */
    VSILFILE *fpVV;
    snprintf( pszImgFile, nImgFileLen, "%s%sIMG-VV%s",
             CPLGetDirname(poOpenInfo->pszFilename), SEP_STRING, pszSuffix );
    fpVV = VSIFOpenL( pszImgFile, "rb" );
    if (fpVV != NULL) {
        poDS->SetBand( nBandNum, new PALSARJaxaRasterBand( poDS, 3, fpVV ) );
        nBandNum++;
    }

    VSIFree( pszImgFile );

    /* did we get at least one band? */
    if (fpVV == NULL && fpVH == NULL && fpHV == NULL && fpHH == NULL) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Unable to find any image data. Aborting opening as PALSAR image.");
        delete poDS;
        VSIFree( pszSuffix );
        return NULL;
    }

    /* Level 1.0 products are not supported */
    if (poDS->nFileType == level_10) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ALOS PALSAR Level 1.0 products are not supported. Aborting opening as PALSAR image.");
        delete poDS;
        VSIFree( pszSuffix );
        return NULL;
    }

    /* read metadata from Leader file. */
    const size_t nLeaderFilenameLen = strlen( CPLGetDirname( poOpenInfo->pszFilename ) ) +
        strlen(pszSuffix) + 5;
    char *pszLeaderFilename = (char *)CPLMalloc( nLeaderFilenameLen );
    snprintf( pszLeaderFilename, nLeaderFilenameLen, "%s%sLED%s",
             CPLGetDirname( poOpenInfo->pszFilename ) , SEP_STRING, pszSuffix );

    VSILFILE *fpLeader = VSIFOpenL( pszLeaderFilename, "rb" );
    /* check if the leader is actually present */
    if (fpLeader != NULL) {
        ReadMetadata(poDS, fpLeader);
        VSIFCloseL(fpLeader);
    }

    VSIFree(pszLeaderFilename);

    VSIFree( pszSuffix );

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

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

    return poDS;
}
Exemple #20
0
CPLErr JP2LuraRasterBand::IRasterIO(GDALRWFlag eRWFlag,
                                    int nXOff, int nYOff, int nXSize, int nYSize,
                                    void * pData, int nBufXSize, int nBufYSize,
                                    GDALDataType eBufType,
                                    GSpacing nPixelSpace, GSpacing nLineSpace,
                                    GDALRasterIOExtraArg* psExtraArg)
{
    JP2LuraDataset *poGDS = reinterpret_cast<JP2LuraDataset *>(poDS);
    const int nBufTypeSize = GDALGetDataTypeSizeBytes(eBufType);

    if (eRWFlag != GF_Read)
        return CE_Failure;

#ifdef DEBUG_VERBOSE
    CPLDebug("JP2Lura", "RasterIO(nBand=%d,nLevel=%d %d,%d,%dx%d -> %dx%d)",
             nBand, poGDS->iLevel, nXOff, nYOff, nXSize, nYSize,
             nBufXSize, nBufYSize);
#endif
    if( eBufType != eDataType ||
        nPixelSpace != nBufTypeSize ||
        nLineSpace != nPixelSpace * nBufXSize )
    {
        return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
                                        pData, nBufXSize, nBufYSize, eBufType,
                                        nPixelSpace, nLineSpace, psExtraArg);
    }

    // Use cached data
    if( poGDS->sOutputData.nXOff == nXOff &&
        poGDS->sOutputData.nYOff == nYOff &&
        poGDS->sOutputData.nXSize == nXSize &&
        poGDS->sOutputData.nYSize == nYSize &&
        poGDS->sOutputData.nBufXSize == nBufXSize &&
        poGDS->sOutputData.nBufYSize == nBufYSize &&
        poGDS->sOutputData.eBufType == eBufType )
    {
        if (poGDS->sOutputData.pDatacache[nBand - 1] != nullptr)
        {
#ifdef DEBUG_VERBOSE
            CPLDebug("JP2Lura", "Using cached data");
#endif
            memcpy(pData, poGDS->sOutputData.pDatacache[nBand - 1],
                   static_cast<size_t>(nBufXSize)*nBufYSize*nBufTypeSize);
            return CE_None;
        }
    }

    /* ==================================================================== */
    /*      Do we have overviews that would be appropriate to satisfy       */
    /*      this request?                                                   */
    /* ==================================================================== */
    if ((nBufXSize < nXSize || nBufYSize < nYSize)
            && GetOverviewCount() > 0 && eRWFlag == GF_Read)
    {
        int         nOverview;
        GDALRasterIOExtraArg sExtraArg;

        GDALCopyRasterIOExtraArg(&sExtraArg, psExtraArg);

        nOverview = GDALBandGetBestOverviewLevel2(
                                        this, nXOff, nYOff, nXSize, nYSize,
                                        nBufXSize, nBufYSize, &sExtraArg);
        if (nOverview >= 0)
        {
            GDALRasterBand* poOverviewBand = GetOverview(nOverview);
            if (poOverviewBand == nullptr)
                    return CE_Failure;

            return poOverviewBand->RasterIO(
                                eRWFlag, nXOff, nYOff, nXSize, nYSize,
                                pData, nBufXSize, nBufYSize, eBufType,
                                nPixelSpace, nLineSpace, &sExtraArg);
        }
    }

    if( nBufXSize != nXSize || nBufYSize != nYSize )
    {
        return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
                                        pData, nBufXSize, nBufYSize, eBufType,
                                        nPixelSpace, nLineSpace, psExtraArg);
    }

    JP2_Error error = 0;
    const short factor = 1 << poGDS->iLevel;

    JP2_Rect comp_region;
    comp_region.ulLeft = nXOff;
    comp_region.ulRight = nXOff + nXSize;
    comp_region.ulTop = nYOff;
    comp_region.ulBottom = nYOff + nYSize;

    error = JP2_Decompress_SetProp(poGDS->sOutputData.handle,
                                   cJP2_Prop_Scale_Down, factor);
    if( error )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Internal library error (%s).",
                 JP2LuraDataset::GetErrorMessage(error));
        return CE_Failure;
    }

    poGDS->sOutputData.pimage = reinterpret_cast<unsigned char*>(pData);

    poGDS->sOutputData.nXOff = nXOff;
    poGDS->sOutputData.nYOff = nYOff;
    poGDS->sOutputData.nXSize = nXSize;
    poGDS->sOutputData.nYSize = nYSize;
    poGDS->sOutputData.nBufXSize = nBufXSize;
    poGDS->sOutputData.nBufYSize = nBufYSize;
    poGDS->sOutputData.eBufType = eBufType;

    poGDS->sOutputData.nBand = nBand;
    poGDS->sOutputData.nBands = poGDS->nBands;
    if( poGDS->sOutputData.pDatacache == nullptr )
    {
        poGDS->sOutputData.pDatacache = reinterpret_cast<unsigned char**>
                            (CPLCalloc( poGDS->nBands, sizeof(unsigned char*)));
    }

    for (int i = 0; i < poGDS->nBands; i++)
    {
        if (poGDS->sOutputData.pDatacache[i] != nullptr)
        {
            VSIFree(poGDS->sOutputData.pDatacache[i]);
            poGDS->sOutputData.pDatacache[i] = nullptr;
        }
        if (i == nBand-1)
            continue;
        poGDS->sOutputData.pDatacache[i] =
            reinterpret_cast<unsigned char*>(VSIMalloc(
                        static_cast<size_t>(nBufXSize)*nBufYSize*nBufTypeSize));
    }

    /*++++++++++++++++++++++++++++++++++++++++++++++*/
    /* Set the callback function and parameter      */
    /*++++++++++++++++++++++++++++++++++++++++++++++*/

    error = JP2_Decompress_SetProp(poGDS->sOutputData.handle,
                cJP2_Prop_Output_Parameter,
                reinterpret_cast<JP2_Property_Value>(&(poGDS->sOutputData)));
    if( error )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Internal library error (%s).",
                 JP2LuraDataset::GetErrorMessage(error));
        return CE_Failure;
    }

    error = JP2_Decompress_SetProp(poGDS->sOutputData.handle,
                    cJP2_Prop_Output_Function,
                    reinterpret_cast<JP2_Property_Value>(
                                    GDALJP2Lura_Callback_Decompress_Write));
    if( error )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Internal library error (%s).",
                 JP2LuraDataset::GetErrorMessage(error));
        return CE_Failure;
    }

    error = JP2_Decompress_Region(poGDS->sOutputData.handle, comp_region);
    if( error )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Internal library error during decompress region (%s).",
                 JP2LuraDataset::GetErrorMessage(error));
        return CE_Failure;
    }

    return CE_None;
}
CPLErr GSBGRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
				    void *pImage )

{
    if( eAccess == GA_ReadOnly )
    {
	CPLError( CE_Failure, CPLE_NoWriteAccess,
		  "Unable to write block, dataset opened read only.\n" );
	return CE_Failure;
    }

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

    GSBGDataset *poGDS = dynamic_cast<GSBGDataset *>(poDS);
    assert( poGDS != NULL );

    if( pafRowMinZ == NULL || pafRowMaxZ == NULL
	|| nMinZRow < 0 || nMaxZRow < 0 )
    {
	pafRowMinZ = (float *)VSIMalloc2( nRasterYSize,sizeof(float) );
	if( pafRowMinZ == NULL )
	{
	    CPLError( CE_Failure, CPLE_OutOfMemory,
		      "Unable to allocate space for row minimums array.\n" );
	    return CE_Failure;
	}

	pafRowMaxZ = (float *)VSIMalloc2( nRasterYSize,sizeof(float) );
	if( pafRowMaxZ == NULL )
	{
	    VSIFree( pafRowMinZ );
	    pafRowMinZ = NULL;
	    CPLError( CE_Failure, CPLE_OutOfMemory,
		      "Unable to allocate space for row maximums array.\n" );
	    return CE_Failure;
	}

	CPLErr eErr = ScanForMinMaxZ();
	if( eErr != CE_None )
	    return eErr;
    }

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

    float *pfImage = (float *)pImage;
    pafRowMinZ[nBlockYOff] = FLT_MAX;
    pafRowMaxZ[nBlockYOff] = -FLT_MAX;
    for( int iPixel=0; iPixel<nBlockXSize; iPixel++ )
    {
	if( pfImage[iPixel] != GSBGDataset::fNODATA_VALUE )
	{
	    if( pfImage[iPixel] < pafRowMinZ[nBlockYOff] )
		pafRowMinZ[nBlockYOff] = pfImage[iPixel];

	    if( pfImage[iPixel] > pafRowMaxZ[nBlockYOff] )
		pafRowMaxZ[nBlockYOff] = pfImage[iPixel];
	}

	CPL_LSBPTR32( pfImage+iPixel );
    }

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

    /* Update min/max Z values as appropriate */
    bool bHeaderNeedsUpdate = false;
    if( nMinZRow == nBlockYOff && pafRowMinZ[nBlockYOff] > dfMinZ )
    {
	double dfNewMinZ = DBL_MAX;
	for( int iRow=0; iRow<nRasterYSize; iRow++ )
	{
	    if( pafRowMinZ[iRow] < dfNewMinZ )
	    {
		dfNewMinZ = pafRowMinZ[iRow];
		nMinZRow = iRow;
	    }
	}

	if( dfNewMinZ != dfMinZ )
	{
	    dfMinZ = dfNewMinZ;
	    bHeaderNeedsUpdate = true;
	}
    }

    if( nMaxZRow == nBlockYOff && pafRowMaxZ[nBlockYOff] < dfMaxZ )
    {
	double dfNewMaxZ = -DBL_MAX;
	for( int iRow=0; iRow<nRasterYSize; iRow++ )
	{
	    if( pafRowMaxZ[iRow] > dfNewMaxZ )
	    {
		dfNewMaxZ = pafRowMaxZ[iRow];
		nMaxZRow = iRow;
	    }
	}

	if( dfNewMaxZ != dfMaxZ )
	{
	    dfMaxZ = dfNewMaxZ;
	    bHeaderNeedsUpdate = true;
	}
    }

    if( pafRowMinZ[nBlockYOff] < dfMinZ || pafRowMaxZ[nBlockYOff] > dfMaxZ )
    {
	if( pafRowMinZ[nBlockYOff] < dfMinZ )
	{
	    dfMinZ = pafRowMinZ[nBlockYOff];
	    nMinZRow = nBlockYOff;
	}

	if( pafRowMaxZ[nBlockYOff] > dfMaxZ )
	{
	    dfMaxZ = pafRowMaxZ[nBlockYOff];
	    nMaxZRow = nBlockYOff;
	}

	bHeaderNeedsUpdate = true;
    }

    if( bHeaderNeedsUpdate && dfMaxZ > dfMinZ )
    {
	CPLErr eErr = poGDS->WriteHeader( poGDS->fp,
					  (GInt16) nRasterXSize, 
                                          (GInt16) nRasterYSize,
					  dfMinX, dfMaxX,
					  dfMinY, dfMaxY,
					  dfMinZ, dfMaxZ );
	return eErr;
    }

    return CE_None;
}
Exemple #22
0
void CPLDebug( const char * pszCategory, const char * pszFormat, ... )

{
    CPLErrorContext *psCtx = CPLGetErrorContext();
    char        *pszMessage;
    va_list     args;
    const char  *pszDebug = CPLGetConfigOption("CPL_DEBUG",NULL);

#define ERROR_MAX 25000

/* -------------------------------------------------------------------- */
/*      Does this message pass our current criteria?                    */
/* -------------------------------------------------------------------- */
    if( pszDebug == NULL )
        return;

    if( !EQUAL(pszDebug,"ON") && !EQUAL(pszDebug,"") )
    {
        size_t  i, nLen = strlen(pszCategory);

        for( i = 0; pszDebug[i] != '\0'; i++ )
        {
            if( EQUALN(pszCategory,pszDebug+i,nLen) )
                break;
        }

        if( pszDebug[i] == '\0' )
            return;
    }

/* -------------------------------------------------------------------- */
/*    Allocate a block for the error.                                   */
/* -------------------------------------------------------------------- */
    pszMessage = (char *) VSIMalloc( ERROR_MAX );
    if( pszMessage == NULL )
        return;
        
/* -------------------------------------------------------------------- */
/*      Dal -- always log a timestamp as the first part of the line     */
/*      to ensure one is looking at what one should be looking at!      */
/* -------------------------------------------------------------------- */

    pszMessage[0] = '\0';
#ifdef TIMESTAMP_DEBUG
    if( CPLGetConfigOption( "CPL_TIMESTAMP", NULL ) != NULL )
    {
        strcpy( pszMessage, VSICTime( VSITime(NULL) ) );
        
        // On windows anyway, ctime puts a \n at the end, but I'm not 
        // convinced this is standard behaviour, so we'll get rid of it
        // carefully

        if (pszMessage[strlen(pszMessage) -1 ] == '\n')
        {
            pszMessage[strlen(pszMessage) - 1] = 0; // blow it out
        }
        strcat( pszMessage, ": " );
    }
#endif

/* -------------------------------------------------------------------- */
/*      Add the category.                                               */
/* -------------------------------------------------------------------- */
    strcat( pszMessage, pszCategory );
    strcat( pszMessage, ": " );
    
/* -------------------------------------------------------------------- */
/*      Format the application provided portion of the debug message.   */
/* -------------------------------------------------------------------- */
    va_start(args, pszFormat);
#if defined(HAVE_VSNPRINTF)
    vsnprintf(pszMessage+strlen(pszMessage), ERROR_MAX - strlen(pszMessage), 
              pszFormat, args);
#else
    vsprintf(pszMessage+strlen(pszMessage), pszFormat, args);
#endif
    va_end(args);

/* -------------------------------------------------------------------- */
/*      Invoke the current error handler.                               */
/* -------------------------------------------------------------------- */
    if( psCtx->psHandlerStack != NULL )
    {
        psCtx->psHandlerStack->pfnHandler( CE_Debug, CPLE_None, pszMessage );
    }
    else
    {
        CPLMutexHolderD( &hErrorMutex );
        if( pfnErrorHandler != NULL )
            pfnErrorHandler( CE_Debug, CPLE_None, pszMessage );
    }

    VSIFree( pszMessage );
}
Exemple #23
0
GDALDataset *
EpsilonDatasetCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                       int bStrict, char ** papszOptions, 
                       GDALProgressFunc pfnProgress, void * pProgressData )
{
    int nBands = poSrcDS->GetRasterCount();
    if ((nBands != 1 && nBands != 3) ||
        (nBands > 0 && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL))
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "The EPSILON driver only supports 1 band (grayscale) "
                 "or 3 band (RGB) data");
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Fetch and check creation options                                */
/* -------------------------------------------------------------------- */

    int nBlockXSize =
        atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
    int nBlockYSize =
        atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
    if ((nBlockXSize != 32 && nBlockXSize != 64 && nBlockXSize != 128 &&
         nBlockXSize != 256 && nBlockXSize != 512 && nBlockXSize != 1024) ||
        (nBlockYSize != 32 && nBlockYSize != 64 && nBlockYSize != 128 &&
         nBlockYSize != 256 && nBlockYSize != 512 && nBlockYSize != 1024))
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                "Block size must be a power of 2 between 32 et 1024");
        return NULL;
    }         
    
    const char* pszFilter =
        CSLFetchNameValueDef(papszOptions, "FILTER", "daub97lift");
    char** papszFBID = eps_get_fb_info(EPS_FB_ID);
    char** papszFBIDIter = papszFBID;
    int bFound = FALSE;
    int nIndexFB = 0;
    while(papszFBIDIter && *papszFBIDIter && !bFound)
    {
        if (strcmp(*papszFBIDIter, pszFilter) == 0)
            bFound = TRUE;
        else
            nIndexFB ++;
        papszFBIDIter ++;
    }
    eps_free_fb_info(papszFBID);
    if (!bFound)
    {
        CPLError(CE_Failure, CPLE_NotSupported, "FILTER='%s' not supported",
                 pszFilter);
        return NULL;
    }
    
    int eMode = EPS_MODE_OTLPF;
    const char* pszMode = CSLFetchNameValueDef(papszOptions, "MODE", "OTLPF");
    if (EQUAL(pszMode, "NORMAL"))
        eMode = EPS_MODE_NORMAL;
    else if (EQUAL(pszMode, "OTLPF"))
        eMode = EPS_MODE_OTLPF;
    else
    {
        CPLError(CE_Failure, CPLE_NotSupported, "MODE='%s' not supported",
                 pszMode);
        return NULL;
    }
    
    char** papszFBType = eps_get_fb_info(EPS_FB_TYPE);
    int bIsBiOrthogonal = EQUAL(papszFBType[nIndexFB], "biorthogonal");
    eps_free_fb_info(papszFBType);
    
    if (eMode == EPS_MODE_OTLPF && !bIsBiOrthogonal)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "MODE=OTLPF can only be used with biorthogonal filters. "
                 "Use MODE=NORMAL instead");
        return NULL;
    }    
    
    int bRasterliteOutput =
        CSLTestBoolean(CSLFetchNameValueDef(papszOptions,
                                            "RASTERLITE_OUTPUT", "NO"));
             
    int nYRatio = EPS_Y_RT;
    int nCbRatio = EPS_Cb_RT;
    int nCrRatio = EPS_Cr_RT;
    
    int eResample;
    if (CSLTestBoolean(CSLFetchNameValueDef(papszOptions,
                                            "RGB_RESAMPLE", "YES")))
        eResample = EPS_RESAMPLE_420;
    else
        eResample = EPS_RESAMPLE_444;
    
    const char* pszTarget = CSLFetchNameValueDef(papszOptions, "TARGET", "96");
    double dfReductionFactor = 1 - atof(pszTarget) / 100;
    if (dfReductionFactor > 1)
        dfReductionFactor = 1;
    else if (dfReductionFactor < 0)
        dfReductionFactor = 0;
    
/* -------------------------------------------------------------------- */
/*      Open file                                                       */
/* -------------------------------------------------------------------- */

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

/* -------------------------------------------------------------------- */
/*      Compute number of blocks, block size, etc...                    */
/* -------------------------------------------------------------------- */

    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    if (eMode == EPS_MODE_OTLPF)
    {
        nBlockXSize ++;
        nBlockYSize ++;
    }
    int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;
    int nBlocks = nXBlocks * nYBlocks;
    int nUncompressedFileSize = nXSize * nYSize * nBands;
    int nUncompressedBlockSize = nUncompressedFileSize / nBlocks;
    int nTargetBlockSize = (int) (dfReductionFactor * nUncompressedBlockSize);
    if (nBands == 1)
        nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_GRAYSCALE_BUF + 1);
    else
        nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_TRUECOLOR_BUF + 1);

/* -------------------------------------------------------------------- */
/*      Allocate work buffers                                           */
/* -------------------------------------------------------------------- */

    GByte* pabyBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands);
    if (pabyBuffer == NULL)
    {
        VSIFCloseL(fp);
        return NULL;
    }
    
    GByte* pabyOutBuf = (GByte*)VSIMalloc(nTargetBlockSize);
    if (pabyOutBuf == NULL)
    {
        VSIFree(pabyBuffer);
        VSIFCloseL(fp);
        return NULL;
    }
    
    GByte** apapbyRawBuffer[3];
    int i, j;
    for(i=0;i<nBands;i++)
    {
        apapbyRawBuffer[i] = (GByte**) VSIMalloc(sizeof(GByte*) * nBlockYSize);
        for(j=0;j<nBlockYSize;j++)
        {
            apapbyRawBuffer[i][j] =
                            pabyBuffer + (i * nBlockXSize + j) * nBlockYSize;
        }
    }
    
    if (bRasterliteOutput)
    {
        const char* pszHeader = RASTERLITE_WAVELET_HEADER;
        VSIFWriteL(pszHeader, 1, strlen(pszHeader) + 1, fp);
    }

/* -------------------------------------------------------------------- */
/*      Iterate over blocks                                             */
/* -------------------------------------------------------------------- */

    int nBlockXOff, nBlockYOff;
    CPLErr eErr = CE_None;
    for(nBlockYOff = 0;
        eErr == CE_None && nBlockYOff < nYBlocks; nBlockYOff ++)
    {
        for(nBlockXOff = 0;
            eErr == CE_None && nBlockXOff < nXBlocks; nBlockXOff ++)
        {
            int bMustMemset = FALSE;
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nXSize)
            {
                bMustMemset = TRUE;
                nReqXSize = nXSize - nBlockXOff * nBlockXSize;
            }
            if ((nBlockYOff+1) * nBlockYSize > nYSize)
            {
                bMustMemset = TRUE;
                nReqYSize = nYSize - nBlockYOff * nBlockYSize;
            }
            if (bMustMemset)
                memset(pabyBuffer, 0, nBands * nBlockXSize * nBlockYSize);
            
            eErr = poSrcDS->RasterIO(GF_Read,
                              nBlockXOff * nBlockXSize,
                              nBlockYOff * nBlockYSize,
                              nReqXSize, nReqYSize,
                              pabyBuffer,
                              nReqXSize, nReqYSize,
                              GDT_Byte, nBands, NULL,
                              1,
                              nBlockXSize,
                              nBlockXSize * nBlockYSize);
            
            int nOutBufSize = nTargetBlockSize;
            if (eErr == CE_None && nBands == 1)
            {
                if (EPS_OK != eps_encode_grayscale_block(apapbyRawBuffer[0],
                                           nXSize, nYSize,
                                           nReqXSize, nReqYSize,
                                           nBlockXOff * nBlockXSize,
                                           nBlockYOff * nBlockYSize,
                                           pabyOutBuf, &nOutBufSize,
                                           (char*) pszFilter, eMode))
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Error occured when encoding block (%d, %d)",
                             nBlockXOff, nBlockYOff);
                    eErr = CE_Failure;
                }
            }
            else if (eErr == CE_None)
            {
                if (EPS_OK != eps_encode_truecolor_block(
                                           apapbyRawBuffer[0],
                                           apapbyRawBuffer[1],
                                           apapbyRawBuffer[2],
                                           nXSize, nYSize,
                                           nReqXSize, nReqYSize,
                                           nBlockXOff * nBlockXSize,
                                           nBlockYOff * nBlockYSize,
                                           eResample,
                                           pabyOutBuf, &nOutBufSize,
                                           nYRatio, nCbRatio, nCrRatio,
                                           (char*) pszFilter, eMode))
                {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Error occured when encoding block (%d, %d)",
                             nBlockXOff, nBlockYOff);
                    eErr = CE_Failure;
                }
            }
            
            if (eErr == CE_None)
            {
                if ((int)VSIFWriteL(pabyOutBuf, 1, nOutBufSize, fp) !=
                                                                nOutBufSize)
                    eErr = CE_Failure;

                char chEPSMarker = EPS_MARKER;
                VSIFWriteL(&chEPSMarker, 1, 1, fp);
                
                if (pfnProgress && !pfnProgress(
                      1.0 * (nBlockYOff * nXBlocks + nBlockXOff + 1) / nBlocks,
                      NULL, pProgressData))
                {
                    eErr = CE_Failure;
                }
            }
        }
    }
    
    if (bRasterliteOutput)
    {
        const char* pszFooter = RASTERLITE_WAVELET_FOOTER;
        VSIFWriteL(pszFooter, 1, strlen(pszFooter) + 1, fp);
    }

/* -------------------------------------------------------------------- */
/*      Cleanup work buffers                                            */
/* -------------------------------------------------------------------- */
    
    for(i=0;i<nBands;i++)
    {
        VSIFree(apapbyRawBuffer[i]);
    }
    
    VSIFree(pabyOutBuf);
    VSIFree(pabyBuffer);
        
    VSIFCloseL(fp);
    
    if (eErr != CE_None)
        return NULL;

/* -------------------------------------------------------------------- */
/*      Reopen the dataset, unless asked for not (Rasterlite optim)     */
/* -------------------------------------------------------------------- */
    return (GDALDataset*) GDALOpen(pszFilename, GA_ReadOnly);
}
static CPLString GIFCollectXMPMetadata(VSILFILE* fp)

{
    CPLString osXMP;

    /* Save current position to avoid disturbing GIF stream decoding */
    vsi_l_offset nCurOffset = VSIFTellL(fp);

    char abyBuffer[2048+1];

    VSIFSeekL( fp, 0, SEEK_SET );

    /* Loop over file */

    int iStartSearchOffset = 1024;
    while(TRUE)
    {
        int nRead = VSIFReadL( abyBuffer + 1024, 1, 1024, fp );
        if (nRead <= 0)
            break;
        abyBuffer[1024 + nRead] = 0;

        int i;
        int iFoundOffset = -1;
        for(i=iStartSearchOffset;i<1024+nRead - 14;i++)
        {
            if (memcmp(abyBuffer + i, "\x21\xff\x0bXMP DataXMP", 14) == 0)
            {
                iFoundOffset = i + 14;
                break;
            }
        }

        iStartSearchOffset = 0;

        if (iFoundOffset >= 0)
        {
            int nSize = 1024 + nRead - iFoundOffset;
            char* pszXMP = (char*)VSIMalloc(nSize + 1);
            if (pszXMP == NULL)
                break;

            pszXMP[nSize] = 0;
            memcpy(pszXMP, abyBuffer + iFoundOffset, nSize);

            /* Read from file until we find a NUL character */
            int nLen = (int)strlen(pszXMP);
            while(nLen == nSize)
            {
                char* pszNewXMP = (char*)VSIRealloc(pszXMP, nSize + 1024 + 1);
                if (pszNewXMP == NULL)
                    break;
                pszXMP = pszNewXMP;

                nRead = VSIFReadL( pszXMP + nSize, 1, 1024, fp );
                if (nRead <= 0)
                    break;

                pszXMP[nSize + nRead] = 0;
                nLen += (int)strlen(pszXMP + nSize);
                nSize += nRead;
            }

            if (nLen > 256 && pszXMP[nLen - 1] == '\x01' &&
                pszXMP[nLen - 2] == '\x02' && pszXMP[nLen - 255] == '\xff' &&
                pszXMP[nLen - 256] == '\x01')
            {
                pszXMP[nLen - 256] = 0;

                osXMP = pszXMP;
            }

            VSIFree(pszXMP);

            break;
        }

        if (nRead != 1024)
            break;

        memcpy(abyBuffer, abyBuffer + 1024, 1024);
    }

    VSIFSeekL( fp, nCurOffset, SEEK_SET );

    return osXMP;
}
Exemple #25
0
GDALDataset *MEMDataset::Create( const char * /* pszFilename */,
                                 int nXSize,
                                 int nYSize,
                                 int nBands,
                                 GDALDataType eType,
                                 char **papszOptions )
{

/* -------------------------------------------------------------------- */
/*      Do we want a pixel interleaved buffer?  I mostly care about     */
/*      this to test pixel interleaved IO in other contexts, but it     */
/*      could be useful to create a directly accessible buffer for      */
/*      some apps.                                                      */
/* -------------------------------------------------------------------- */
    bool bPixelInterleaved = false;
    const char *pszOption = CSLFetchNameValue( papszOptions, "INTERLEAVE" );
    if( pszOption && EQUAL(pszOption,"PIXEL") )
        bPixelInterleaved = true;

/* -------------------------------------------------------------------- */
/*      First allocate band data, verifying that we can get enough      */
/*      memory.                                                         */
/* -------------------------------------------------------------------- */
    const int nWordSize = GDALGetDataTypeSize(eType) / 8;
    if( nBands > 0 && nWordSize > 0 && (nBands > INT_MAX / nWordSize ||
        (GIntBig)nXSize * nYSize > GINTBIG_MAX / (nWordSize * nBands)) )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, "Multiplication overflow");
        return NULL;
    }

    const GUIntBig nGlobalBigSize
        = static_cast<GUIntBig>(nWordSize) * nBands * nXSize * nYSize;
    const size_t nGlobalSize = static_cast<size_t>(nGlobalBigSize);
#if SIZEOF_VOIDP == 4
    if( static_cast<GUIntBig>(nGlobalSize) != nGlobalBigSize )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory,
                  "Cannot allocate " CPL_FRMT_GUIB " bytes on this platform.",
                  nGlobalBigSize );
        return NULL;
    }
#endif

    std::vector<GByte*> apbyBandData;
    bool bAllocOK = true;

    if( bPixelInterleaved )
    {
        apbyBandData.push_back(
            reinterpret_cast<GByte *>( VSI_CALLOC_VERBOSE( 1, nGlobalSize ) ) );

        if( apbyBandData[0] == NULL )
            bAllocOK = FALSE;
        else
        {
            for( int iBand = 1; iBand < nBands; iBand++ )
                apbyBandData.push_back( apbyBandData[0] + iBand * nWordSize );
        }
    }
    else
    {
        for( int iBand = 0; iBand < nBands; iBand++ )
        {
            apbyBandData.push_back(
                reinterpret_cast<GByte *>(
                    VSI_CALLOC_VERBOSE(
                        1,
                        static_cast<size_t>(nWordSize) * nXSize * nYSize ) ) );
            if( apbyBandData[iBand] == NULL )
            {
                bAllocOK = FALSE;
                break;
            }
        }
    }

    if( !bAllocOK )
    {
        for( int iBand = 0;
             iBand < static_cast<int>( apbyBandData.size() );
             iBand++ )
        {
            if( apbyBandData[iBand] )
                VSIFree( apbyBandData[iBand] );
        }
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the new GTiffDataset object.                             */
/* -------------------------------------------------------------------- */
    MEMDataset *poDS = new MEMDataset();

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

    const char *pszPixelType = CSLFetchNameValue( papszOptions, "PIXELTYPE" );
    if( pszPixelType && EQUAL(pszPixelType, "SIGNEDBYTE") )
        poDS->SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" );

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

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    for( int iBand = 0; iBand < nBands; iBand++ )
    {
        MEMRasterBand *poNewBand = NULL;

        if( bPixelInterleaved )
            poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand],
                                           eType, nWordSize * nBands, 0,
                                           iBand == 0 );
        else
            poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand],
                                           eType, 0, 0, TRUE );

        poDS->SetBand( iBand+1, poNewBand );
    }

/* -------------------------------------------------------------------- */
/*      Try to return a regular handle on the file.                     */
/* -------------------------------------------------------------------- */
    return poDS;
}
Exemple #26
0
OGRErr OGRPolygon::exportToWkt( char ** ppszDstText,
                                OGRwkbVariant eWkbVariant ) const

{
    OGRErr      eErr;
    bool        bMustWriteComma = false;

/* -------------------------------------------------------------------- */
/*      If we have no valid exterior ring, return POLYGON EMPTY.        */
/* -------------------------------------------------------------------- */
    if (getExteriorRing() == NULL ||
        getExteriorRing()->IsEmpty() )
    {
        if( eWkbVariant == wkbVariantIso )
        {
            if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) )
                *ppszDstText = CPLStrdup("POLYGON ZM EMPTY");
            else if( flags & OGR_G_MEASURED )
                *ppszDstText = CPLStrdup("POLYGON M EMPTY");
            else if( flags & OGR_G_3D )
                *ppszDstText = CPLStrdup("POLYGON Z EMPTY");
            else
                *ppszDstText = CPLStrdup("POLYGON EMPTY");
        }
        else
            *ppszDstText = CPLStrdup("POLYGON EMPTY");
        return OGRERR_NONE;
    }

/* -------------------------------------------------------------------- */
/*      Build a list of strings containing the stuff for each ring.     */
/* -------------------------------------------------------------------- */
    char **papszRings = (char **) CPLCalloc(sizeof(char *),oCC.nCurveCount);
    size_t nCumulativeLength = 0;
    size_t nNonEmptyRings = 0;
    size_t *pnRingBeginning = (size_t *) CPLCalloc(sizeof(size_t),oCC.nCurveCount);

    for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ )
    {
        OGRLinearRing* poLR = (OGRLinearRing*) oCC.papoCurves[iRing];
        //poLR->setFlags( getFlags() );
        poLR->set3D(Is3D());
        poLR->setMeasured(IsMeasured());
        if( poLR->getNumPoints() == 0 )
        {
            papszRings[iRing] = NULL;
            continue;
        }

        eErr = poLR->exportToWkt( &(papszRings[iRing]), eWkbVariant );
        if( eErr != OGRERR_NONE )
            goto error;

        if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING ZM (") )
            pnRingBeginning[iRing] = 14;
        else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING M (") )
            pnRingBeginning[iRing] = 13;
        else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING Z (") )
            pnRingBeginning[iRing] = 13;
        else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING (") )
            pnRingBeginning[iRing] = 11;
        else
        {
            CPLAssert( 0 );
        }

        nCumulativeLength += strlen(papszRings[iRing] + pnRingBeginning[iRing]);

        nNonEmptyRings++;
    }

/* -------------------------------------------------------------------- */
/*      Allocate exactly the right amount of space for the              */
/*      aggregated string.                                              */
/* -------------------------------------------------------------------- */
    *ppszDstText = (char *) VSI_MALLOC_VERBOSE(nCumulativeLength + nNonEmptyRings + 16);

    if( *ppszDstText == NULL )
    {
        eErr = OGRERR_NOT_ENOUGH_MEMORY;
        goto error;
    }

/* -------------------------------------------------------------------- */
/*      Build up the string, freeing temporary strings as we go.        */
/* -------------------------------------------------------------------- */
    if( eWkbVariant == wkbVariantIso )
    {
        if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) )
            strcpy( *ppszDstText, "POLYGON ZM (" );
        else if( flags & OGR_G_MEASURED )
            strcpy( *ppszDstText, "POLYGON M (" );
        else if( flags & OGR_G_3D )
            strcpy( *ppszDstText, "POLYGON Z (" );
        else
            strcpy( *ppszDstText, "POLYGON (" );
    }
    else
        strcpy( *ppszDstText, "POLYGON (" );
    nCumulativeLength = strlen(*ppszDstText);

    for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ )
    {
        if( papszRings[iRing] == NULL )
        {
            CPLDebug( "OGR", "OGRPolygon::exportToWkt() - skipping empty ring.");
            continue;
        }

        if( bMustWriteComma )
            (*ppszDstText)[nCumulativeLength++] = ',';
        bMustWriteComma = true;

        size_t nRingLen = strlen(papszRings[iRing] + pnRingBeginning[iRing]);
        memcpy( *ppszDstText + nCumulativeLength, papszRings[iRing] + pnRingBeginning[iRing], nRingLen );
        nCumulativeLength += nRingLen;
        VSIFree( papszRings[iRing] );
    }

    (*ppszDstText)[nCumulativeLength++] = ')';
    (*ppszDstText)[nCumulativeLength] = '\0';

    CPLFree( papszRings );
    CPLFree( pnRingBeginning );

    return OGRERR_NONE;

error:
    for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ )
        CPLFree(papszRings[iRing]);
    CPLFree(papszRings);
    return eErr;
}
Exemple #27
0
CPLErr GSAGDataset::ShiftFileContents( VSILFILE *fp, vsi_l_offset nShiftStart,
				       int nShiftSize, const char *pszEOL )
{
    /* nothing to do for zero-shift */
    if( nShiftSize == 0 )
	return CE_None;

    /* make sure start location is sane */
    if( nShiftStart < 0
	|| (nShiftSize < 0
	    && nShiftStart < static_cast<vsi_l_offset>(-nShiftSize)) )
	nShiftStart = (nShiftSize > 0) ? 0 : -nShiftSize;

    /* get offset at end of file */
    if( VSIFSeekL( fp, 0, SEEK_END ) != 0 )
    {
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to end of grid file.\n" );
	return CE_Failure;
    }

    vsi_l_offset nOldEnd = VSIFTellL( fp );

    /* If shifting past end, just zero-pad as necessary */
    if( nShiftStart >= nOldEnd )
    {
	if( nShiftSize < 0 )
	{
	    if( nShiftStart + nShiftSize >= nOldEnd )
		return CE_None;

	    if( VSIFSeekL( fp, nShiftStart + nShiftSize, SEEK_SET ) != 0 )
	    {
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to seek near end of file.\n" );
		return CE_Failure;
	    }

	    /* ftruncate()? */
	    for( vsi_l_offset nPos = nShiftStart + nShiftSize;
		 nPos > nOldEnd; nPos++ )
	    {
		if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
		{
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write padding to grid file "
			      "(Out of space?).\n" );
		    return CE_Failure;
		}
	    }

	    return CE_None;
	}
	else
	{
	    for( vsi_l_offset nPos = nOldEnd;
		 nPos < nShiftStart + nShiftSize; nPos++ )
	    {
		if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
		{
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write padding to grid file "
			      "(Out of space?).\n" );
		    return CE_Failure;
		}
	    }
	    return CE_None;
	}
    }

    /* prepare buffer for real shifting */
    size_t nBufferSize = (1024 >= abs(nShiftSize)*2) ? 1024 : abs(nShiftSize)*2;
    char *pabyBuffer = (char *)VSIMalloc( nBufferSize );
    if( pabyBuffer == NULL)
    {
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to allocate space for shift buffer.\n" );
	return CE_Failure;
    }

    if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 )
    {
	VSIFree( pabyBuffer );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of shift in grid file.\n" );
	return CE_Failure;
    }

    size_t nRead;
    size_t nOverlap = (nShiftSize > 0) ? nShiftSize : 0;
    /* If there is overlap, fill buffer with the overlap to start */
    if( nOverlap > 0)
    {
	nRead = VSIFReadL( (void *)pabyBuffer, 1, nOverlap, fp );
	if( nRead < nOverlap && !VSIFEofL( fp ) )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Error reading grid file.\n" );
	    return CE_Failure;
	}

	/* overwrite the new space with ' ' */
    	if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to seek to start of shift in grid file.\n" );
	    return CE_Failure;
	}

	for( int iFill=0; iFill<nShiftSize; iFill++ )
	{
	    if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
	    {
		VSIFree( pabyBuffer );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to write padding to grid file "
			  "(Out of space?).\n" );
		return CE_Failure;
	    }
	}

	/* if we have already read the entire file, finish it off */
	if( VSIFTellL( fp ) >= nOldEnd )
	{
	    if( VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp ) != nRead )
	    {
		VSIFree( pabyBuffer );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to write to grid file (Out of space?).\n" );
		return CE_Failure;
	    }

	    VSIFree( pabyBuffer );
	    return CE_None;
	}
    }

    /* iterate over the remainder of the file and shift as requested */
    bool bEOF = false;
    while( !bEOF )
    {
	nRead = VSIFReadL( (void *)(pabyBuffer+nOverlap), 1,
			   nBufferSize - nOverlap, fp );

        if( VSIFEofL( fp ) )
            bEOF = true;
        else 
            bEOF = false;

	if( nRead == 0 && !bEOF )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to read from grid file (possible corruption).\n");
	    return CE_Failure;
	}

	/* FIXME:  Should use SEEK_CUR, review integer promotions... */
	if( VSIFSeekL( fp, VSIFTellL(fp)-nRead+nShiftSize-nOverlap,
		       SEEK_SET ) != 0 )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to seek in grid file (possible corruption).\n" );
	    return CE_Failure;
	}

	size_t nWritten = VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp );
	if( nWritten != nRead )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}

	/* shift overlapped contents to the front of the buffer if necessary */
	if( nOverlap > 0)
	    memmove(pabyBuffer, pabyBuffer+nRead, nOverlap);
    }

    /* write the remainder of the buffer or overwrite leftovers and finish */
    if( nShiftSize > 0 )
    {
	size_t nTailSize = nOverlap;
	while( nTailSize > 0 && isspace( (unsigned char)pabyBuffer[nTailSize-1] ) )
	    nTailSize--;

	if( VSIFWriteL( (void *)pabyBuffer, 1, nTailSize, fp ) != nTailSize )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}

	if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp )
            != strlen(pszEOL) )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}
    }
    else
    {
	/* FIXME: ftruncate()? */
	/* FIXME:  Should use SEEK_CUR, review integer promotions... */
	if( VSIFSeekL( fp, VSIFTellL(fp)-strlen(pszEOL), SEEK_SET ) != 0 )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to seek in grid file.\n" );
	    return CE_Failure;
	}

	for( int iPadding=0; iPadding<-nShiftSize; iPadding++ )
	{
	    if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
	    {
		VSIFree( pabyBuffer );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Error writing to grid file.\n" );
		return CE_Failure;
	    }
	}

	if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp )
            != strlen(pszEOL) )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}
    }

    VSIFree( pabyBuffer );
    return CE_None;
}
Exemple #28
0
GDALDataset* SIGDEMDataset::CreateCopy(
    const char * pszFilename,
    GDALDataset * poSrcDS,
    int /*bStrict*/,
    char ** /*papszOptions*/,
    GDALProgressFunc pfnProgress,
    void * pProgressData) {
    const int nBands = poSrcDS->GetRasterCount();
    double adfGeoTransform[6] = { };
    if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) {
        CPLError(CE_Failure, CPLE_NotSupported,
                "SIGDEM driver requires a valid GeoTransform.");
        return nullptr;
    }

    if (nBands != 1) {
        CPLError(CE_Failure, CPLE_NotSupported,
                "SIGDEM driver doesn't support %d bands.  Must be 1 band.",
                nBands);
        return nullptr;
    }

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

    GDALRasterBand* band = poSrcDS->GetRasterBand(1);
    const char* pszProjection = poSrcDS->GetProjectionRef();

    int32_t nCols = poSrcDS->GetRasterXSize();
    int32_t nRows = poSrcDS->GetRasterYSize();
    int32_t nCoordinateSystemId = GetCoordinateSystemId(pszProjection);

    SIGDEMHeader sHeader;
    sHeader.nCoordinateSystemId = nCoordinateSystemId;
    sHeader.dfMinX = adfGeoTransform[0];
    const char* pszMin = band->GetMetadataItem("STATISTICS_MINIMUM");
    if (pszMin == nullptr) {
        sHeader.dfMinZ = -10000;
    } else {
        sHeader.dfMinZ = CPLAtof(pszMin);
    }
    sHeader.dfMaxY = adfGeoTransform[3];
    const char* pszMax = band->GetMetadataItem("STATISTICS_MAXIMUM");
    if (pszMax == nullptr) {
        sHeader.dfMaxZ = 10000;
    } else {
        sHeader.dfMaxZ = CPLAtof(pszMax);
    }
    sHeader.nCols = poSrcDS->GetRasterXSize();
    sHeader.nRows = poSrcDS->GetRasterYSize();
    sHeader.dfXDim = adfGeoTransform[1];
    sHeader.dfYDim = -adfGeoTransform[5];
    sHeader.dfMaxX = sHeader.dfMinX + sHeader.nCols * sHeader.dfXDim;
    sHeader.dfMinY = sHeader.dfMaxY - sHeader.nRows * sHeader.dfYDim;
    sHeader.dfOffsetX = sHeader.dfMinX;
    sHeader.dfOffsetY = sHeader.dfMinY;

    if( !sHeader.Write(fp) )
    {
        VSIUnlink(pszFilename);
        VSIFCloseL(fp);
        return nullptr;
    }

    // Write fill with all NO_DATA values
    int32_t* row = static_cast<int32_t*>(VSI_MALLOC2_VERBOSE(nCols, sizeof(int32_t)));
    if( !row ) {
        VSIUnlink(pszFilename);
        VSIFCloseL(fp);
        return nullptr;
    }
    std::fill(row, row + nCols, CPL_MSBWORD32(NO_DATA));
    for (int i = 0; i < nRows; i++) {
        if( VSIFWriteL(row, CELL_SIZE_FILE, nCols, fp) !=
                                            static_cast<size_t>(nCols) )
        {
            VSIFree(row);
            VSIUnlink(pszFilename);
            VSIFCloseL(fp);
            return nullptr;
        }
    }
    VSIFree(row);

    if (VSIFCloseL(fp) != 0) {
        return nullptr;
    }

    if (nCoordinateSystemId <= 0) {
        if (!EQUAL(pszProjection, "")) {
            CPLString osPrjFilename = CPLResetExtension(pszFilename, "prj");
            VSILFILE *fpProj = VSIFOpenL(osPrjFilename, "wt");
            if (fpProj != nullptr) {
                OGRSpatialReference oSRS;
                oSRS.importFromWkt(pszProjection);
                oSRS.morphToESRI();
                char *pszESRIProjection = nullptr;
                oSRS.exportToWkt(&pszESRIProjection);
                CPL_IGNORE_RET_VAL(
                        VSIFWriteL(pszESRIProjection, 1,
                                strlen(pszESRIProjection), fpProj));

                CPL_IGNORE_RET_VAL(VSIFCloseL(fpProj));
                CPLFree(pszESRIProjection);
            } else {
                CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.",
                        osPrjFilename.c_str());
            }
        }
    }
    GDALOpenInfo oOpenInfo(pszFilename, GA_Update);
    GDALDataset * poDstDS = Open(&oOpenInfo);
    if (poDstDS != nullptr &&
        GDALDatasetCopyWholeRaster(poSrcDS, poDstDS, nullptr, pfnProgress,
            pProgressData) == OGRERR_NONE) {
        return poDstDS;
    } else {
        VSIUnlink(pszFilename);
        return nullptr;
    }
}
Exemple #29
0
CPLErr GSAGRasterBand::ScanForMinMaxZ()

{
    double *padfRowValues = (double *)VSIMalloc2( nBlockXSize, sizeof(double) );
    if( padfRowValues == NULL )
    {
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to allocate memory for grid row values.\n" );
	return CE_Failure;
    }

    double dfNewMinZ = DBL_MAX;
    double dfNewMaxZ = -DBL_MAX;
    int nNewMinZRow = 0;
    int nNewMaxZRow = 0;

    /* Since we have to scan, lets calc. statistics too */
    double dfSum = 0.0;
    double dfSum2 = 0.0;
    unsigned long nValuesRead = 0;
    for( int iRow=0; iRow<nRasterYSize; iRow++ )
    {
	CPLErr eErr = IReadBlock( 0, iRow, padfRowValues );
	if( eErr != CE_None )
	{
	    VSIFree( padfRowValues );
	    return eErr;
	}

	padfRowMinZ[iRow] = DBL_MAX;
	padfRowMaxZ[iRow] = -DBL_MAX;
	for( int iCell=0; iCell<nRasterXSize; iCell++ )
	{
	    if( AlmostEqual(padfRowValues[iCell], GSAGDataset::dfNODATA_VALUE) )
		continue;

	    if( padfRowValues[iCell] < padfRowMinZ[iRow] )
		padfRowMinZ[iRow] = padfRowValues[iCell];

	    if( padfRowValues[iCell] > padfRowMaxZ[iRow] )
		padfRowMaxZ[iRow] = padfRowValues[iCell];

	    dfSum += padfRowValues[iCell];
	    dfSum2 += padfRowValues[iCell] * padfRowValues[iCell];
	    nValuesRead++;
	}

	if( padfRowMinZ[iRow] < dfNewMinZ )
	{
	    dfNewMinZ = padfRowMinZ[iRow];
	    nNewMinZRow = iRow;
	}

	if( padfRowMaxZ[iRow] > dfNewMaxZ )
	{
	    dfNewMaxZ = padfRowMaxZ[iRow];
	    nNewMaxZRow = iRow;
	}
    }

    VSIFree( padfRowValues );

    if( nValuesRead == 0 )
    {
	dfMinZ = 0.0;
	dfMaxZ = 0.0;
	nMinZRow = 0;
	nMaxZRow = 0;
	return CE_None;
    }

    dfMinZ = dfNewMinZ;
    dfMaxZ = dfNewMaxZ;
    nMinZRow = nNewMinZRow;
    nMaxZRow = nNewMaxZRow;

    double dfMean = dfSum / nValuesRead;
    double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean));
    SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev );

    return CE_None;
}
Exemple #30
0
OGRErr OGRLineString::exportToWkt( char ** ppszDstText ) const

{
    int         nMaxString = nPointCount * 20 * 3 + 20;
    int         nRetLen = 0;

/* -------------------------------------------------------------------- */
/*      Handle special empty case.                                      */
/* -------------------------------------------------------------------- */
    if( nPointCount == 0 )
    {
        *ppszDstText = CPLStrdup("LINESTRING(EMPTY)");
        return OGRERR_NONE;
    }

/* -------------------------------------------------------------------- */
/*      General case.                                                   */
/* -------------------------------------------------------------------- */
    *ppszDstText = (char *) VSIMalloc( nMaxString );
    if( *ppszDstText == NULL )
        return OGRERR_NOT_ENOUGH_MEMORY;

    sprintf( *ppszDstText, "%s (", getGeometryName() );

    for( int i = 0; i < nPointCount; i++ )
    {
        if( nMaxString <= (int) strlen(*ppszDstText+nRetLen) + 32 + nRetLen )
        {
            CPLDebug( "OGR",
                      "OGRLineString::exportToWkt() ... buffer overflow.\n"
                      "nMaxString=%d, strlen(*ppszDstText) = %d, i=%d\n"
                      "*ppszDstText = %s",
                      nMaxString, strlen(*ppszDstText), i, *ppszDstText );

            VSIFree( *ppszDstText );
            *ppszDstText = NULL;
            return OGRERR_NOT_ENOUGH_MEMORY;
        }

        if( i > 0 )
            strcat( *ppszDstText + nRetLen, "," );

        nRetLen += strlen(*ppszDstText + nRetLen);
        if( getCoordinateDimension() == 3 )
            OGRMakeWktCoordinate( *ppszDstText + nRetLen,
                                  paoPoints[i].x,
                                  paoPoints[i].y,
                                  padfZ[i] );
        else
            OGRMakeWktCoordinate( *ppszDstText + nRetLen,
                                  paoPoints[i].x,
                                  paoPoints[i].y,
                                  0.0 );

        nRetLen += strlen(*ppszDstText + nRetLen);
    }

    strcat( *ppszDstText+nRetLen, ")" );

    return OGRERR_NONE;
}