ultimatepp/bazaar/plugin/gdal/frmts/arg/argdataset.cpp
cxl 23ff1e7e82 .gdal moved to bazaar
git-svn-id: svn://ultimatepp.org/upp/trunk@9273 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2015-12-07 13:36:24 +00:00

850 lines
28 KiB
C++

/******************************************************************************
* $Id: argdataset.cpp 28053 2014-12-04 09:31:07Z rouault $
*
* Project: Azavea Raster Grid format driver.
* Purpose: Implements support for reading and writing Azavea Raster Grid
* format.
* Author: David Zwarg <dzwarg@azavea.com>
*
******************************************************************************
* Copyright (c) 2012, David Zwarg <dzwarg@azavea.com>
* Copyright (c) 2012-2013, Even Rouault <even dot rouault at mines-paris dot org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#include "rawdataset.h"
#include "cpl_string.h"
#include <json.h>
#include <ogr_spatialref.h>
CPL_CVSID("$Id: argdataset.cpp 28053 2014-12-04 09:31:07Z rouault $");
#define MAX_FILENAME_LEN 4096
#ifndef NAN
# ifdef HUGE_VAL
# define NAN (HUGE_VAL * 0.0)
# else
static float CPLNaN(void)
{
float fNan;
int nNan = 0x7FC00000;
memcpy(&fNan, &nNan, 4);
return fNan;
}
# define NAN CPLNaN()
# endif
#endif
/************************************************************************/
/* ==================================================================== */
/* ARGDataset */
/* ==================================================================== */
/************************************************************************/
class ARGDataset : public RawDataset
{
VSILFILE *fpImage; // image data file.
double adfGeoTransform[6];
char * pszFilename;
public:
ARGDataset();
~ARGDataset();
CPLErr GetGeoTransform( double * padfTransform );
static int Identify( GDALOpenInfo * );
static GDALDataset *Open( GDALOpenInfo * );
static GDALDataset *CreateCopy( const char *, GDALDataset *, int,
char **, GDALProgressFunc, void *);
virtual char ** GetFileList(void);
};
/************************************************************************/
/* ARGDataset() */
/************************************************************************/
ARGDataset::ARGDataset()
{
adfGeoTransform[0] = 0.0;
adfGeoTransform[1] = 1.0;
adfGeoTransform[2] = 0.0;
adfGeoTransform[3] = 0.0;
adfGeoTransform[4] = 0.0;
adfGeoTransform[5] = 1.0;
fpImage = NULL;
}
/************************************************************************/
/* ~ARGDataset() */
/************************************************************************/
ARGDataset::~ARGDataset()
{
CPLFree(pszFilename);
FlushCache();
if( fpImage != NULL )
VSIFCloseL( fpImage );
}
/************************************************************************/
/* GetGeoTransform() */
/************************************************************************/
CPLErr ARGDataset::GetGeoTransform( double * padfTransform )
{
memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
return CE_None;
}
/************************************************************************/
/* GetJsonFilename() */
/************************************************************************/
CPLString GetJsonFilename(CPLString pszFilename)
{
return CPLSPrintf( "%s/%s.json", CPLGetDirname(pszFilename), CPLGetBasename(pszFilename) );
}
/************************************************************************/
/* GetJsonObject() */
/************************************************************************/
json_object * GetJsonObject(CPLString pszFilename)
{
json_object * pJSONObject = NULL;
CPLString osJSONFilename = GetJsonFilename(pszFilename);
pJSONObject = json_object_from_file((char *)osJSONFilename.c_str());
if (pJSONObject == NULL) {
CPLDebug("ARGDataset", "GetJsonObject(): "
"Could not parse JSON file.");
return NULL;
}
return pJSONObject;
}
/************************************************************************/
/* GetJsonValueStr() */
/************************************************************************/
const char * GetJsonValueStr(json_object * pJSONObject, CPLString pszKey)
{
json_object * pJSONItem = json_object_object_get(pJSONObject, pszKey.c_str());
if (pJSONItem == NULL) {
CPLDebug("ARGDataset", "GetJsonValueStr(): "
"Could not find '%s' in JSON.", pszKey.c_str());
return NULL;
}
return json_object_get_string(pJSONItem);
}
/************************************************************************/
/* GetJsonValueDbl() */
/************************************************************************/
double GetJsonValueDbl(json_object * pJSONObject, CPLString pszKey)
{
const char *pszJSONStr = GetJsonValueStr(pJSONObject, pszKey.c_str());
char *pszTmp;
double fTmp;
if (pszJSONStr == NULL) {
return NAN;
}
pszTmp = (char *)pszJSONStr;
fTmp = CPLStrtod(pszJSONStr, &pszTmp);
if (pszTmp == pszJSONStr) {
CPLDebug("ARGDataset", "GetJsonValueDbl(): "
"Key value is not a numeric value: %s:%s", pszKey.c_str(), pszTmp);
return NAN;
}
return fTmp;
}
/************************************************************************/
/* GetJsonValueInt() */
/************************************************************************/
int GetJsonValueInt(json_object * pJSONObject, CPLString pszKey)
{
double fTmp = GetJsonValueDbl(pJSONObject, pszKey.c_str());
if (CPLIsNan(fTmp)) {
return -1;
}
return (int)fTmp;
}
/************************************************************************/
/* GetFileList() */
/************************************************************************/
char ** ARGDataset::GetFileList()
{
char **papszFileList = GDALPamDataset::GetFileList();
CPLString osJSONFilename = GetJsonFilename(pszFilename);
papszFileList = CSLAddString( papszFileList, osJSONFilename );
return papszFileList;
}
/************************************************************************/
/* Identify() */
/************************************************************************/
int ARGDataset::Identify( GDALOpenInfo *poOpenInfo )
{
json_object * pJSONObject;
if (!EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "arg")) {
return FALSE;
}
pJSONObject = GetJsonObject(poOpenInfo->pszFilename);
if (pJSONObject == NULL) {
return FALSE;
}
json_object_put(pJSONObject);
pJSONObject = NULL;
return TRUE;
}
/************************************************************************/
/* Open() */
/************************************************************************/
GDALDataset *ARGDataset::Open( GDALOpenInfo * poOpenInfo )
{
json_object * pJSONObject;
const char * pszJSONStr;
char * pszLayer;
/***** items from the json metadata *****/
GDALDataType eType = GDT_Unknown;
double fXmin = 0.0;
double fYmin = 0.0;
double fXmax = 0.0;
double fYmax = 0.0;
double fCellwidth = 1.0;
double fCellheight = 1.0;
double fXSkew = 0.0;
double fYSkew = 0.0;
int nRows = 0;
int nCols = 0;
int nSrs = 3857;
/***** items from the json metadata *****/
int nPixelOffset = 0;
double fNoDataValue = NAN;
char * pszWKT = NULL;
OGRSpatialReference oSRS;
OGRErr nErr = OGRERR_NONE;
if ( !Identify( poOpenInfo ) )
return NULL;
/* -------------------------------------------------------------------- */
/* Check metadata settings in JSON. */
/* -------------------------------------------------------------------- */
pJSONObject = GetJsonObject(poOpenInfo->pszFilename);
if (pJSONObject == NULL) {
CPLError(CE_Failure, CPLE_AppDefined, "Error parsing JSON.");
return NULL;
}
// get the type (always 'arg')
pszJSONStr = GetJsonValueStr(pJSONObject, "type");
if (pszJSONStr == NULL ) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'type' is missing from the JSON file.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
else if (!EQUAL(pszJSONStr, "arg")) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'type' is not recognized: '%s'.", pszJSONStr);
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the datatype
pszJSONStr = GetJsonValueStr(pJSONObject, "datatype");
if (pszJSONStr == NULL) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'datatype' is missing from the JSON file.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
else if (EQUAL(pszJSONStr, "int8")) {
CPLDebug("ARGDataset", "Open(): "
"int8 data is not supported in GDAL -- mapped to uint8");
eType = GDT_Byte;
nPixelOffset = 1;
fNoDataValue = 128;
}
else if (EQUAL(pszJSONStr, "int16")) {
eType = GDT_Int16;
nPixelOffset = 2;
fNoDataValue = -32767;
}
else if (EQUAL(pszJSONStr, "int32")) {
eType = GDT_Int32;
nPixelOffset = 4;
fNoDataValue = -2e31;
}
else if (EQUAL(pszJSONStr, "uint8")) {
eType = GDT_Byte;
nPixelOffset = 1;
fNoDataValue = 255;
}
else if (EQUAL(pszJSONStr, "uint16")) {
eType = GDT_UInt16;
nPixelOffset = 2;
fNoDataValue = 65535;
}
else if (EQUAL(pszJSONStr, "uint32")) {
eType = GDT_UInt32;
nPixelOffset = 4;
fNoDataValue = -2e31;
}
else if (EQUAL(pszJSONStr, "float32")) {
eType = GDT_Float32;
nPixelOffset = 4;
fNoDataValue = NAN;
}
else if (EQUAL(pszJSONStr, "float64")) {
eType = GDT_Float64;
nPixelOffset = 8;
fNoDataValue = NAN;
}
else {
if (EQUAL(pszJSONStr, "int64") ||
EQUAL(pszJSONStr, "uint64")) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'datatype' is unsupported in GDAL: '%s'.", pszJSONStr);
}
else {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'datatype' is unknown: '%s'.", pszJSONStr);
}
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the xmin of the bounding box
fXmin = GetJsonValueDbl(pJSONObject, "xmin");
if (CPLIsNan(fXmin)) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'xmin' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the ymin of the bounding box
fYmin = GetJsonValueDbl(pJSONObject, "ymin");
if (CPLIsNan(fYmin)) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'ymin' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the xmax of the bounding box
fXmax = GetJsonValueDbl(pJSONObject, "xmax");
if (CPLIsNan(fXmax)) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'xmax' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the ymax of the bounding box
fYmax = GetJsonValueDbl(pJSONObject, "ymax");
if (CPLIsNan(fYmax)) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'ymax' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the cell width
fCellwidth = GetJsonValueDbl(pJSONObject, "cellwidth");
if (CPLIsNan(fCellwidth)) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'cellwidth' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the cell height
fCellheight = GetJsonValueDbl(pJSONObject, "cellheight");
if (CPLIsNan(fCellheight)) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'cellheight' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
fXSkew = GetJsonValueDbl(pJSONObject, "xskew");
if (CPLIsNan(fXSkew)) {
// not an error -- default to 0.0
fXSkew = 0.0f;
}
fYSkew = GetJsonValueDbl(pJSONObject, "yskew");
if (CPLIsNan(fYSkew)) {
// not an error -- default to 0.0
fYSkew = 0.0f;
}
// get the rows
nRows = GetJsonValueInt(pJSONObject, "rows");
if (nRows < 0) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'rows' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the columns
nCols = GetJsonValueInt(pJSONObject, "cols");
if (nCols < 0) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'cols' is missing or invalid.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
nSrs = GetJsonValueInt(pJSONObject, "epsg");
if (nSrs < 0) {
// not an error -- default to web mercator
nSrs = 3857;
}
nErr = oSRS.importFromEPSG(nSrs);
if (nErr != OGRERR_NONE) {
nErr = oSRS.importFromEPSG(3857);
if (nErr == OGRERR_NONE) {
CPLDebug("ARGDataset", "Open(): "
"The EPSG provided did not import cleanly. Defaulting to EPSG:3857");
}
else {
CPLError(CE_Failure, CPLE_AppDefined,
"The 'epsg' value did not transate to a known spatial reference."
" Please check the 'epsg' value and try again.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
}
nErr = oSRS.exportToWkt(&pszWKT);
if (nErr != OGRERR_NONE) {
CPLError(CE_Failure, CPLE_AppDefined,
"The spatial reference is known, but could not be set on the "
"dataset. Please check the 'epsg' value and try again.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
// get the layer (always the file basename)
pszJSONStr = GetJsonValueStr(pJSONObject, "layer");
if (pszJSONStr == NULL) {
CPLError(CE_Failure, CPLE_AppDefined,
"The ARG 'layer' is missing from the JSON file.");
json_object_put(pJSONObject);
pJSONObject = NULL;
return NULL;
}
pszLayer = CPLStrdup(pszJSONStr);
// done with the json object now
json_object_put(pJSONObject);
pJSONObject = NULL;
/* -------------------------------------------------------------------- */
/* Create a corresponding GDALDataset. */
/* -------------------------------------------------------------------- */
ARGDataset *poDS;
poDS = new ARGDataset();
poDS->pszFilename = CPLStrdup(poOpenInfo->pszFilename);
poDS->SetMetadataItem("LAYER",pszLayer,NULL);
poDS->nRasterXSize = nCols;
poDS->nRasterYSize = nRows;
poDS->SetProjection( pszWKT );
// done with the projection string
CPLFree(pszWKT);
CPLFree(pszLayer);
/* -------------------------------------------------------------------- */
/* Assume ownership of the file handled from the GDALOpenInfo. */
/* -------------------------------------------------------------------- */
poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb");
if (poDS->fpImage == NULL)
{
delete poDS;
CPLError(CE_Failure, CPLE_AppDefined,
"Could not open dataset '%s'", poOpenInfo->pszFilename);
return NULL;
}
poDS->adfGeoTransform[0] = fXmin;
poDS->adfGeoTransform[1] = fCellwidth;
poDS->adfGeoTransform[2] = fXSkew;
poDS->adfGeoTransform[3] = fYmax;
poDS->adfGeoTransform[4] = fYSkew;
poDS->adfGeoTransform[5] = -fCellheight;
/* -------------------------------------------------------------------- */
/* Create band information objects. */
/* -------------------------------------------------------------------- */
RawRasterBand *poBand;
#ifdef CPL_LSB
int bNative = FALSE;
#else
int bNative = TRUE;
#endif
poBand = new RawRasterBand( poDS, 1, poDS->fpImage,
0, nPixelOffset, nPixelOffset * nCols,
eType, bNative, TRUE );
poDS->SetBand( 1, poBand );
poBand->SetNoDataValue( fNoDataValue );
/* -------------------------------------------------------------------- */
/* Initialize any PAM information. */
/* -------------------------------------------------------------------- */
poDS->SetDescription( poOpenInfo->pszFilename );
poDS->TryLoadXML();
/* -------------------------------------------------------------------- */
/* Check for overviews. */
/* -------------------------------------------------------------------- */
poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
return( poDS );
}
/************************************************************************/
/* CreateCopy() */
/************************************************************************/
GDALDataset * ARGDataset::CreateCopy( const char * pszFilename,
GDALDataset * poSrcDS,
CPL_UNUSED int bStrict,
CPL_UNUSED char ** papszOptions,
CPL_UNUSED GDALProgressFunc pfnProgress,
CPL_UNUSED void * pProgressData )
{
int nBands = poSrcDS->GetRasterCount();
int nXSize = poSrcDS->GetRasterXSize();
int nYSize = poSrcDS->GetRasterYSize();
int nXBlockSize, nYBlockSize, nPixelOffset = 0;
GDALDataType eType;
CPLString osJSONFilename;
CPLString pszDataType;
json_object * poJSONObject = NULL;
double adfTransform[6];
GDALRasterBand * poSrcBand = NULL;
RawRasterBand * poDstBand = NULL;
VSILFILE * fpImage = NULL;
void * pabyData;
OGRSpatialReference oSRS;
char * pszWKT = NULL;
char ** pszTokens = NULL;
const char * pszLayer = NULL;
int nSrs = 0;
OGRErr nErr = OGRERR_NONE;
CPLErr eErr;
if( nBands != 1 )
{
CPLError( CE_Failure, CPLE_NotSupported,
"ARG driver doesn't support %d bands. Must be 1 band.", nBands );
return NULL;
}
eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
if( eType == GDT_Unknown ||
eType == GDT_CInt16 ||
eType == GDT_CInt32 ||
eType == GDT_CFloat32 ||
eType == GDT_CFloat64 )
{
CPLError( CE_Failure, CPLE_NotSupported,
"ARG driver doesn't support data type %s.",
GDALGetDataTypeName(eType) );
return NULL;
}
else if (eType == GDT_Int16) {
pszDataType = "int16";
nPixelOffset = 2;
}
else if (eType == GDT_Int32) {
pszDataType = "int32";
nPixelOffset = 4;
}
else if (eType == GDT_Byte) {
pszDataType = "uint8";
nPixelOffset = 1;
}
else if (eType == GDT_UInt16) {
pszDataType = "uint16";
nPixelOffset = 2;
}
else if (eType == GDT_UInt32) {
pszDataType = "uint32";
nPixelOffset = 4;
}
else if (eType == GDT_Float32) {
pszDataType = "float32";
nPixelOffset = 4;
}
else if (eType == GDT_Float64) {
pszDataType = "float64";
nPixelOffset = 8;
}
poSrcDS->GetGeoTransform( adfTransform );
pszWKT = (char *)poSrcDS->GetProjectionRef();
nErr = oSRS.importFromWkt(&pszWKT);
if (nErr != OGRERR_NONE) {
CPLError( CE_Failure, CPLE_NotSupported,
"Cannot import spatial reference WKT from source dataset.");
return NULL;
}
if (oSRS.GetAuthorityCode("PROJCS") != NULL) {
nSrs = atoi(oSRS.GetAuthorityCode("PROJCS"));
}
else if (oSRS.GetAuthorityCode("GEOGCS") != NULL) {
nSrs = atoi(oSRS.GetAuthorityCode("GEOGCS"));
}
else {
// could not determine projected or geographic code
// default to EPSG:3857 if no code could be found
nSrs = 3857;
}
/********************************************************************/
/* Create JSON companion file. */
/********************************************************************/
osJSONFilename = GetJsonFilename(pszFilename);
poJSONObject = json_object_new_object();
pszTokens = poSrcDS->GetMetadata();
pszLayer = CSLFetchNameValue(pszTokens, "LAYER");
if ( pszLayer == NULL) {
// Set the layer
json_object_object_add(poJSONObject, "layer", json_object_new_string(
CPLGetBasename(osJSONFilename)
));
}
else {
// Set the layer
json_object_object_add(poJSONObject, "layer", json_object_new_string(
pszLayer
));
}
// Set the type
json_object_object_add(poJSONObject, "type", json_object_new_string("arg"));
// Set the datatype
json_object_object_add(poJSONObject, "datatype", json_object_new_string(pszDataType));
// Set the number of rows
json_object_object_add(poJSONObject, "rows", json_object_new_int(nYSize));
// Set the number of columns
json_object_object_add(poJSONObject, "cols", json_object_new_int(nXSize));
// Set the xmin
json_object_object_add(poJSONObject, "xmin", json_object_new_double(adfTransform[0]));
// Set the ymax
json_object_object_add(poJSONObject, "ymax", json_object_new_double(adfTransform[3]));
// Set the cellwidth
json_object_object_add(poJSONObject, "cellwidth", json_object_new_double(adfTransform[1]));
// Set the cellheight
json_object_object_add(poJSONObject, "cellheight", json_object_new_double(-adfTransform[5]));
// Set the xmax
json_object_object_add(poJSONObject, "xmax", json_object_new_double(adfTransform[0] + nXSize * adfTransform[1]));
// Set the ymin
json_object_object_add(poJSONObject, "ymin", json_object_new_double(adfTransform[3] + nYSize * adfTransform[5]));
// Set the xskew
json_object_object_add(poJSONObject, "xskew", json_object_new_double(adfTransform[2]));
// Set the yskew
json_object_object_add(poJSONObject, "yskew", json_object_new_double(adfTransform[4]));
if (nSrs > 0) {
// Set the epsg
json_object_object_add(poJSONObject, "epsg", json_object_new_int(nSrs));
}
if (json_object_to_file((char *)osJSONFilename.c_str(), poJSONObject) < 0) {
CPLError( CE_Failure, CPLE_NotSupported,
"ARG driver can't write companion file.");
json_object_put(poJSONObject);
poJSONObject = NULL;
return NULL;
}
json_object_put(poJSONObject);
poJSONObject = NULL;
fpImage = VSIFOpenL(pszFilename, "wb");
if (fpImage == NULL)
{
CPLError( CE_Failure, CPLE_NotSupported,
"ARG driver can't create data file %s.", pszFilename);
// remove JSON file
VSIUnlink( osJSONFilename.c_str() );
return NULL;
}
// only 1 raster band
poSrcBand = poSrcDS->GetRasterBand( 1 );
#ifdef CPL_LSB
int bNative = FALSE;
#else
int bNative = TRUE;
#endif
poDstBand = new RawRasterBand( fpImage, 0, nPixelOffset,
nPixelOffset * nXSize, eType, bNative,
nXSize, nYSize, TRUE, FALSE);
poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize);
pabyData = CPLMalloc(nXBlockSize * nPixelOffset);
// convert any blocks into scanlines
for (int nYBlock = 0; nYBlock * nYBlockSize < nYSize; nYBlock++) {
for (int nYScanline = 0; nYScanline < nYBlockSize; nYScanline++) {
if ((nYScanline+1) + nYBlock * nYBlockSize > poSrcBand->GetYSize() ) {
continue;
}
for (int nXBlock = 0; nXBlock * nXBlockSize < nXSize; nXBlock++) {
int nXValid;
if( (nXBlock+1) * nXBlockSize > poSrcBand->GetXSize() )
nXValid = poSrcBand->GetXSize() - nXBlock * nXBlockSize;
else
nXValid = nXBlockSize;
eErr = poSrcBand->RasterIO(GF_Read, nXBlock * nXBlockSize,
nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize,
1, eType, 0, 0, NULL);
if (eErr != CE_None) {
CPLError(CE_Failure, CPLE_AppDefined, "Error reading.");
CPLFree( pabyData );
delete poDstBand;
VSIFCloseL( fpImage );
return NULL;
}
eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize,
nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize,
1, eType, 0, 0, NULL);
if (eErr != CE_None) {
CPLError(CE_Failure, CPLE_AppDefined, "Error writing.");
CPLFree( pabyData );
delete poDstBand;
VSIFCloseL( fpImage );
return NULL;
}
}
}
}
CPLFree( pabyData );
delete poDstBand;
VSIFCloseL( fpImage );
return (GDALDataset *)GDALOpen( pszFilename, GA_ReadOnly );
}
/************************************************************************/
/* GDALRegister_ARG() */
/************************************************************************/
void GDALRegister_ARG()
{
GDALDriver *poDriver;
if( GDALGetDriverByName( "ARG" ) == NULL )
{
poDriver = new GDALDriver();
poDriver->SetDescription( "ARG" );
poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" );
poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
"Azavea Raster Grid format" );
poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
"frmt_various.html#ARG" );
poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
poDriver->pfnIdentify = ARGDataset::Identify;
poDriver->pfnOpen = ARGDataset::Open;
poDriver->pfnCreateCopy = ARGDataset::CreateCopy;
GetGDALDriverManager()->RegisterDriver( poDriver );
}
}