diff --git a/autotest/gdrivers/arg.py b/autotest/gdrivers/arg.py deleted file mode 100755 index 23524e5d1f66..000000000000 --- a/autotest/gdrivers/arg.py +++ /dev/null @@ -1,338 +0,0 @@ -#!/usr/bin/env pytest -############################################################################### -# $Id$ -# -# Project: GDAL/OGR Test Suite -# Purpose: ARG Testing. -# Author: David Zwarg -# -############################################################################### -# Copyright (c) 2012, David Zwarg -# -# 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. -############################################################################### - -import os -import struct -from copy import copy - -import gdaltest -import pytest - -from osgeo import gdal - -pytestmark = [ - pytest.mark.require_driver("ARG"), - pytest.mark.random_order(disabled=True), -] - -# given fmt and nodata, encodes a value as bytes - -############################################################################### -@pytest.fixture(autouse=True, scope="module") -def module_disable_exceptions(): - with gdaltest.config_option("GDAL_ENABLE_DEPRECATED_DRIVER_ARG", "YES"): - yield - - -def pack(fmt, nodata, value): - if value is None: - value = nodata - return struct.pack(fmt, value) - - -# packs the given values together as bytes - - -def encode(fmt, nodata, values): - chunks = [pack(fmt, nodata, v) for v in values] - return "".encode("ascii").join(chunks) - - -############################################################################### -# - - -def test_arg_init(): - gdaltest.argDriver = gdal.GetDriverByName("ARG") - if gdaltest.argDriver is None: - pytest.skip() - - gdaltest.argJsontpl = """{ - "layer": "%(fmt)s", - "type": "arg", - "datatype": "%(dt)s", - "xmin": %(xmin)f, - "ymin": %(ymin)f, - "xmax": %(xmax)f, - "ymax": %(ymax)f, - "cellwidth": %(width)f, - "cellheight": %(height)f, - "rows": %(rows)d, - "cols": %(cols)d -}""" - gdaltest.argDefaults = { - "xmin": 0.0, - "ymin": 0.0, - "xmax": 2.0, - "ymax": 2.0, - "width": 1.0, - "height": 1.0, - "rows": 2, - "cols": 2, - } - - # None means "no data" - gdaltest.argTests = [ - { - "formats": [ - ("int8", ">b", -(1 << 7)), - ("int16", ">h", -(1 << 15)), - ("int32", ">i", -(1 << 31)), - ("int64", ">q", -(1 << 63)), - ], - "data": [None, 2, -3, -4], - }, - { - "formats": [ - ("uint8", ">B", (1 << 8) - 1), - ("uint16", ">H", (1 << 16) - 1), - ("uint32", ">I", (1 << 32) - 1), - ("uint64", ">Q", (1 << 64) - 1), - ], - "data": [None, 2, 3, 4], - }, - { - "formats": [ - ("float32", ">f", gdaltest.NaN()), - ("float64", ">d", gdaltest.NaN()), - ], - "data": [None, 1.1, -20.02, 300.003], - }, - ] - - for d in gdaltest.argTests: - for (name, fmt, nodata) in d["formats"]: - arg = open("data/arg-" + name + ".arg", "wb") - arg.write(encode(fmt, nodata, d["data"])) - arg.close() - - meta = copy(gdaltest.argDefaults) - meta.update(fmt="arg-" + name, dt=name) - json = open("data/arg-" + name + ".json", "w") - json.write(gdaltest.argJsontpl % meta) - json.close() - - ds = gdal.Open("data/arg-" + gdaltest.argTests[0]["formats"][1][0] + ".arg") - if ds is None: - gdaltest.argDriver = None - - if gdaltest.argDriver is None: - pytest.skip() - - -def test_arg_unsupported(): - if gdaltest.argDriver is None: - pytest.skip() - - for d in gdaltest.argTests: - for (name, _, _) in d["formats"]: - ds = gdal.Open("data/arg-" + name + ".arg") - assert ds is not None - - -def test_arg_getrastercount(): - if gdaltest.argDriver is None: - pytest.skip() - - for d in gdaltest.argTests: - for (name, _, _) in d["formats"]: - with gdaltest.error_handler("CPLQuietErrorHandler"): - ds = gdal.Open("data/arg-" + name + ".arg") - if ds is None: - continue - - assert ds.RasterCount == 1 - - -def test_arg_getgeotransform(): - if gdaltest.argDriver is None: - pytest.skip() - - for d in gdaltest.argTests: - for (name, _, _) in d["formats"]: - with gdaltest.error_handler("CPLQuietErrorHandler"): - ds = gdal.Open("data/arg-" + name + ".arg") - if ds is None: - continue - - gt = ds.GetGeoTransform() - - assert ( - gt[0] == 0 - and gt[1] == 1 - and gt[2] == 0 - and gt[3] == 2 - and gt[4] == 0 - and gt[5] == -1 - ) - - -def test_arg_blocksize(): - if gdaltest.argDriver is None: - pytest.skip() - - tifDriver = gdal.GetDriverByName("GTiff") - assert tifDriver is not None - - ds = gdal.Open("data/utm.tif") - xsize = ds.RasterXSize - ysize = ds.RasterYSize - - # create a blocked tiff, where blocks don't line up evenly - # with the image boundary - ds2 = tifDriver.CreateCopy( - "data/utm-uneven-blocks.tif", - ds, - False, - ["BLOCKXSIZE=25", "BLOCKYSIZE=25", "TILED=NO"], - ) - - # convert the new blocked tiff to arg - ds = gdaltest.argDriver.CreateCopy("data/utm.arg", ds2, False) - - ds2 = None - ds = None - - stat = os.stat("data/utm.arg") - - os.remove("data/utm-uneven-blocks.tif") - gdal.GetDriverByName("ARG").Delete("data/utm.arg") - - assert stat.st_size == (xsize * ysize) - - -def test_arg_layername(): - """ - The layer name of the ARG in the .json file need not be the name of - the .arg file. The original driver enforced this constraint, but that - behavior was wrong. See ticket #4609 - """ - if gdaltest.argDriver is None: - pytest.skip() - - ds = gdal.Open("data/arg-int16.arg") - - lyr = "ARG FTW" - - # set the layer name - ds.SetMetadataItem("LAYER", lyr) - - # did the layer name stick? - assert ds.GetMetadata()["LAYER"] == lyr - - # copy the dataset to a new ARG - ds2 = gdaltest.argDriver.CreateCopy("data/arg-int16-2.arg", ds, False) - - ds = None - del ds2 - - # open the new dataset - ds = gdal.Open("data/arg-int16-2.arg") - - lyr2 = ds.GetMetadata()["LAYER"] - - ds = None - gdal.GetDriverByName("ARG").Delete("data/arg-int16-2.arg") - - # does the new dataset's layer match the layer set before copying - assert lyr2 == lyr - - os.unlink("data/arg-int16.arg.aux.xml") - - -def test_arg_nodata(): - """ - Check that the NoData value for int8 images is 128, as per the - ARG spec. See ticket #4610 - """ - if gdaltest.argDriver is None: - pytest.skip() - - ds = gdal.Open("data/arg-int8.arg") - - assert ds.GetRasterBand(1).GetNoDataValue() == 128 - - -def test_arg_byteorder(): - """ - Check that a roundtrip from ARG -> GTiff -> ARG has the same - binary values. See ticket #4779 - - Unfortunately, computing statistics yields different results - when the binary data is the same. Compare them byte-by-byte. - """ - if gdaltest.argDriver is None: - pytest.skip() - - tifDriver = gdal.GetDriverByName("GTiff") - assert tifDriver is not None - - for d in gdaltest.argTests: - for (name, _, _) in d["formats"]: - - basename = "data/arg-" + name - with gdaltest.error_handler("CPLQuietErrorHandler"): - orig = gdal.Open(basename + ".arg") - if orig is None: - continue - - dest = tifDriver.CreateCopy(basename + ".tif", orig, False) - assert dest is not None - - mirror = gdaltest.argDriver.CreateCopy(basename + "2.arg", dest, False) - assert mirror is not None - - orig = None - dest = None - mirror = None - - tmp1 = open(basename + ".arg", "rb") - tmp2 = open(basename + "2.arg", "rb") - - data1 = tmp1.read() - data2 = tmp2.read() - - tmp1.close() - tmp2.close() - - gdal.GetDriverByName("GTiff").Delete(basename + ".tif") - gdal.GetDriverByName("ARG").Delete(basename + "2.arg") - - assert data1 == data2 - - -def test_arg_destroy(): - if gdaltest.argDriver is None: - pytest.skip() - - for d in gdaltest.argTests: - for (name, _, _) in d["formats"]: - os.remove("data/arg-" + name + ".arg") - os.remove("data/arg-" + name + ".json") diff --git a/doc/source/drivers/raster/arg.rst b/doc/source/drivers/raster/arg.rst deleted file mode 100644 index 914ea945e117..000000000000 --- a/doc/source/drivers/raster/arg.rst +++ /dev/null @@ -1,37 +0,0 @@ -.. _raster.arg: - -================================================================================ -ARG -- Azavea Raster Grid -================================================================================ - -.. shortname:: ARG - -.. built_in_by_default:: - -Driver implementation for a raw format that is used in -`GeoTrellis `__ and called ARG. `ARG format -specification `__. -Format is essentially a raw format, with a companion .JSON file. - -.. warning:: - - This driver is deprecated (https://github.com/OSGeo/gdal/issues/7920) and - will be removed in GDAL 3.9. You are invited to convert any dataset in that - format to another more common one. - If you need this driver in future GDAL versions, create a ticket at - https://github.com/OSGeo/gdal (look first for an existing one first) - to explain how critical it is for you (but the GDAL project may still remove it) - - -NOTE: Implemented as :source_file:`frmts/arg/argdataset.cpp`. - -Driver capabilities -------------------- - -.. supports_createcopy:: - -.. supports_create:: - -.. supports_georeferencing:: - -.. supports_virtualio:: diff --git a/doc/source/drivers/raster/index.rst b/doc/source/drivers/raster/index.rst index c48f6603e207..9469711283c7 100644 --- a/doc/source/drivers/raster/index.rst +++ b/doc/source/drivers/raster/index.rst @@ -30,7 +30,6 @@ Raster drivers adrg aig airsar - arg bag basisu blx diff --git a/frmts/CMakeLists.txt b/frmts/CMakeLists.txt index 01265cdd8ad6..7e62b82072eb 100644 --- a/frmts/CMakeLists.txt +++ b/frmts/CMakeLists.txt @@ -86,7 +86,6 @@ gdal_optional_format(stacta "STACTA") # optional Formats gdal_optional_format(bsb "Maptech/NOAA BSB Nautical Chart Format") gdal_dependent_format(aigrid "Arc/Info Binary Grid Format" "OGR_ENABLE_DRIVER_AVC") -gdal_optional_format(arg "ARG: Azavea Raster Grid") gdal_optional_format(usgsdem "USGS ASCII DEM (and CDED)") gdal_optional_format(airsar "AirSAR Polarimetric Format") gdal_optional_format(ozi "OZF2/OZFX3 raster") diff --git a/frmts/arg/CMakeLists.txt b/frmts/arg/CMakeLists.txt deleted file mode 100644 index 9c050dab7403..000000000000 --- a/frmts/arg/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_gdal_driver(TARGET gdal_ARG SOURCES argdataset.cpp PLUGIN_CAPABLE_IF "NOT GDAL_USE_JSONC_INTERNAL" NO_DEPS) -gdal_standard_includes(gdal_ARG) -target_include_directories(gdal_ARG PRIVATE $ - $) -if (GDAL_USE_JSONC_INTERNAL) - gdal_add_vendored_lib(gdal_ARG libjson) -else () - gdal_target_link_libraries(gdal_ARG PRIVATE ${JSONC_TARGET}) -endif () diff --git a/frmts/arg/argdataset.cpp b/frmts/arg/argdataset.cpp deleted file mode 100644 index 800375e05a62..000000000000 --- a/frmts/arg/argdataset.cpp +++ /dev/null @@ -1,916 +0,0 @@ -/****************************************************************************** - * - * Project: Azavea Raster Grid format driver. - * Purpose: Implements support for reading and writing Azavea Raster Grid - * format. - * Author: David Zwarg - * - ****************************************************************************** - * Copyright (c) 2012, David Zwarg - * Copyright (c) 2012-2013, Even Rouault - * - * 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 "cpl_string.h" -#include "gdal_frmts.h" -#include "ogr_spatialref.h" -#include "rawdataset.h" - -#include "ogrgeojsonreader.h" -#include - -/************************************************************************/ -/* ==================================================================== */ -/* ARGDataset */ -/* ==================================================================== */ -/************************************************************************/ - -class ARGDataset final : public RawDataset -{ - VSILFILE *fpImage; // image data file. - double adfGeoTransform[6]; - char *pszFilename; - - CPLErr Close() override; - - public: - ARGDataset(); - ~ARGDataset() override; - - CPLErr GetGeoTransform(double *padfTransform) override; - - static int Identify(GDALOpenInfo *); - static GDALDataset *Open(GDALOpenInfo *); - static GDALDataset *CreateCopy(const char *, GDALDataset *, int, char **, - GDALProgressFunc, void *); - char **GetFileList(void) override; -}; - -/************************************************************************/ -/* ARGDataset() */ -/************************************************************************/ - -ARGDataset::ARGDataset() : fpImage(nullptr), pszFilename(nullptr) -{ - adfGeoTransform[0] = 0.0; - adfGeoTransform[1] = 1.0; - adfGeoTransform[2] = 0.0; - adfGeoTransform[3] = 0.0; - adfGeoTransform[4] = 0.0; - adfGeoTransform[5] = 1.0; -} - -/************************************************************************/ -/* ~ARGDataset() */ -/************************************************************************/ - -ARGDataset::~ARGDataset() - -{ - ARGDataset::Close(); -} - -/************************************************************************/ -/* Close() */ -/************************************************************************/ - -CPLErr ARGDataset::Close() -{ - CPLErr eErr = CE_None; - if (nOpenFlags != OPEN_FLAGS_CLOSED) - { - if (ARGDataset::FlushCache(true) != CE_None) - eErr = CE_Failure; - - if (fpImage != nullptr) - { - if (VSIFCloseL(fpImage) != 0) - { - CPLError(CE_Failure, CPLE_FileIO, "I/O error"); - eErr = CE_Failure; - } - } - - CPLFree(pszFilename); - - if (GDALPamDataset::Close() != CE_None) - eErr = CE_Failure; - } - return eErr; -} - -/************************************************************************/ -/* GetGeoTransform() */ -/************************************************************************/ - -CPLErr ARGDataset::GetGeoTransform(double *padfTransform) - -{ - memcpy(padfTransform, adfGeoTransform, sizeof(double) * 6); - - return CE_None; -} - -/************************************************************************/ -/* GetJsonFilename() */ -/************************************************************************/ -static std::string GetJsonFilename(const std::string &pszFilename) -{ - return CPLSPrintf("%s/%s.json", CPLGetDirname(pszFilename.c_str()), - CPLGetBasename(pszFilename.c_str())); -} - -/************************************************************************/ -/* GetJsonObject() */ -/************************************************************************/ -static json_object *GetJsonObject(const std::string &pszFilename) -{ - const std::string osJSONFilename = GetJsonFilename(pszFilename); - - json_object *pJSONObject = - json_object_from_file(const_cast(osJSONFilename.c_str())); - if (pJSONObject == nullptr) - { - CPLDebug("ARGDataset", "GetJsonObject(): Could not parse JSON file."); - return nullptr; - } - - return pJSONObject; -} - -/************************************************************************/ -/* GetJsonValueStr() */ -/************************************************************************/ -static const char *GetJsonValueStr(json_object *pJSONObject, - const std::string &pszKey) -{ - json_object *pJSONItem = - CPL_json_object_object_get(pJSONObject, pszKey.c_str()); - if (pJSONItem == nullptr) - { - CPLDebug("ARGDataset", - "GetJsonValueStr(): " - "Could not find '%s' in JSON.", - pszKey.c_str()); - return nullptr; - } - - return json_object_get_string(pJSONItem); -} - -/************************************************************************/ -/* GetJsonValueDbl() */ -/************************************************************************/ -static double GetJsonValueDbl(json_object *pJSONObject, - const std::string &pszKey) -{ - const char *pszJSONStr = GetJsonValueStr(pJSONObject, pszKey.c_str()); - if (pszJSONStr == nullptr) - { - return std::numeric_limits::quiet_NaN(); - } - char *pszTmp = const_cast(pszJSONStr); - double dfTmp = CPLStrtod(pszJSONStr, &pszTmp); - if (pszTmp == pszJSONStr) - { - CPLDebug("ARGDataset", - "GetJsonValueDbl(): " - "Key value is not a numeric value: %s:%s", - pszKey.c_str(), pszTmp); - return std::numeric_limits::quiet_NaN(); - } - - return dfTmp; -} - -/************************************************************************/ -/* GetJsonValueInt() */ -/************************************************************************/ -static int GetJsonValueInt(json_object *pJSONObject, const std::string &pszKey) -{ - const double dfTmp = GetJsonValueDbl(pJSONObject, pszKey.c_str()); - if (CPLIsNan(dfTmp)) - { - return -1; - } - - return static_cast(dfTmp); -} - -/************************************************************************/ -/* GetFileList() */ -/************************************************************************/ -char **ARGDataset::GetFileList() -{ - char **papszFileList = GDALPamDataset::GetFileList(); - CPLString osJSONFilename = GetJsonFilename(pszFilename); - - papszFileList = CSLAddString(papszFileList, osJSONFilename); - - return papszFileList; -} - -/************************************************************************/ -/* Identify() */ -/************************************************************************/ - -int ARGDataset::Identify(GDALOpenInfo *poOpenInfo) -{ -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if (!EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "arg")) - { - return FALSE; - } -#endif - - json_object *pJSONObject = GetJsonObject(poOpenInfo->pszFilename); - if (pJSONObject == nullptr) - { - return FALSE; - } - - json_object_put(pJSONObject); - pJSONObject = nullptr; - - return TRUE; -} - -/************************************************************************/ -/* Open() */ -/************************************************************************/ -GDALDataset *ARGDataset::Open(GDALOpenInfo *poOpenInfo) -{ - if (!Identify(poOpenInfo) || poOpenInfo->fpL == nullptr) - return nullptr; - - if (!GDALIsDriverDeprecatedForGDAL39StillEnabled("ARG")) - return nullptr; - - /* -------------------------------------------------------------------- */ - /* Confirm the requested access is supported. */ - /* -------------------------------------------------------------------- */ - if (poOpenInfo->eAccess == GA_Update) - { - CPLError(CE_Failure, CPLE_NotSupported, - "The ARG driver does not support update access to existing" - " datasets."); - return nullptr; - } - /* -------------------------------------------------------------------- */ - /* Check metadata settings in JSON. */ - /* -------------------------------------------------------------------- */ - - json_object *pJSONObject = GetJsonObject(poOpenInfo->pszFilename); - - if (pJSONObject == nullptr) - { - CPLError(CE_Failure, CPLE_AppDefined, "Error parsing JSON."); - return nullptr; - } - - // get the type (always 'arg') - const char *pszJSONStr = GetJsonValueStr(pJSONObject, "type"); - if (pszJSONStr == nullptr) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'type' is missing from the JSON file."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - else if (!EQUAL(pszJSONStr, "arg")) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'type' is not recognized: '%s'.", pszJSONStr); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - double dfNoDataValue; - GDALDataType eType; - int nPixelOffset; - - // get the datatype - pszJSONStr = GetJsonValueStr(pJSONObject, "datatype"); - if (pszJSONStr == nullptr) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'datatype' is missing from the JSON file."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - else if (EQUAL(pszJSONStr, "int8")) - { - CPLDebug("ARGDataset", - "Open(): " - "int8 data is not supported in GDAL -- mapped to uint8"); - eType = GDT_Byte; - nPixelOffset = 1; - dfNoDataValue = 128; - } - else if (EQUAL(pszJSONStr, "int16")) - { - eType = GDT_Int16; - nPixelOffset = 2; - dfNoDataValue = -32767; - } - else if (EQUAL(pszJSONStr, "int32")) - { - eType = GDT_Int32; - nPixelOffset = 4; - dfNoDataValue = -2e31; - } - else if (EQUAL(pszJSONStr, "int64")) - { - eType = GDT_Int64; - nPixelOffset = 8; - dfNoDataValue = static_cast(static_cast( - static_cast(std::numeric_limits::min()))); - } - else if (EQUAL(pszJSONStr, "uint8")) - { - eType = GDT_Byte; - nPixelOffset = 1; - dfNoDataValue = 255; - } - else if (EQUAL(pszJSONStr, "uint16")) - { - eType = GDT_UInt16; - nPixelOffset = 2; - dfNoDataValue = 65535; - } - else if (EQUAL(pszJSONStr, "uint32")) - { - eType = GDT_UInt32; - nPixelOffset = 4; - dfNoDataValue = 2e31; - } - else if (EQUAL(pszJSONStr, "uint64")) - { - eType = GDT_UInt64; - nPixelOffset = 8; - dfNoDataValue = static_cast(static_cast( - static_cast(std::numeric_limits::max()))); - } - else if (EQUAL(pszJSONStr, "float32")) - { - eType = GDT_Float32; - nPixelOffset = 4; - dfNoDataValue = std::numeric_limits::quiet_NaN(); - } - else if (EQUAL(pszJSONStr, "float64")) - { - eType = GDT_Float64; - nPixelOffset = 8; - dfNoDataValue = std::numeric_limits::quiet_NaN(); - } - else - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'datatype' is unknown: '%s'.", pszJSONStr); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - // get the xmin of the bounding box - const double dfXmin = GetJsonValueDbl(pJSONObject, "xmin"); - if (CPLIsNan(dfXmin)) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'xmin' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - // get the ymin of the bounding box - const double dfYmin = GetJsonValueDbl(pJSONObject, "ymin"); - if (CPLIsNan(dfYmin)) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'ymin' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - // get the xmax of the bounding boxfpL - const double dfXmax = GetJsonValueDbl(pJSONObject, "xmax"); - if (CPLIsNan(dfXmax)) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'xmax' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - // get the ymax of the bounding box - const double dfYmax = GetJsonValueDbl(pJSONObject, "ymax"); - if (CPLIsNan(dfYmax)) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'ymax' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - // get the cell width - const double dfCellwidth = GetJsonValueDbl(pJSONObject, "cellwidth"); - if (CPLIsNan(dfCellwidth)) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'cellwidth' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - // get the cell height - const double dfCellheight = GetJsonValueDbl(pJSONObject, "cellheight"); - if (CPLIsNan(dfCellheight)) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'cellheight' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - double dfXSkew = GetJsonValueDbl(pJSONObject, "xskew"); - if (CPLIsNan(dfXSkew)) - { - // not an error -- default to 0.0 - dfXSkew = 0.0f; - } - - double dfYSkew = GetJsonValueDbl(pJSONObject, "yskew"); - if (CPLIsNan(dfYSkew)) - { - // not an error -- default to 0.0 - dfYSkew = 0.0f; - } - - // get the rows - const int nRows = GetJsonValueInt(pJSONObject, "rows"); - if (nRows < 0) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'rows' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - // get the columns - const int nCols = GetJsonValueInt(pJSONObject, "cols"); - if (nCols < 0) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'cols' is missing or invalid."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - return nullptr; - } - - int nSrs = GetJsonValueInt(pJSONObject, "epsg"); - if (nSrs < 0) - { - // not an error -- default to web mercator - nSrs = 3857; - } - - OGRSpatialReference oSRS; - OGRErr 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 translate to a known " - "spatial reference. " - "Please check the 'epsg' value and try again."); - - json_object_put(pJSONObject); - pJSONObject = nullptr; - - return nullptr; - } - } - - char *pszWKT = nullptr; - 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 = nullptr; - CPLFree(pszWKT); - return nullptr; - } - - // get the layer (always the file basename) - pszJSONStr = GetJsonValueStr(pJSONObject, "layer"); - if (pszJSONStr == nullptr) - { - CPLError(CE_Failure, CPLE_AppDefined, - "The ARG 'layer' is missing from the JSON file."); - json_object_put(pJSONObject); - pJSONObject = nullptr; - CPLFree(pszWKT); - return nullptr; - } - - char *pszLayer = CPLStrdup(pszJSONStr); - - // done with the json object now - json_object_put(pJSONObject); - pJSONObject = nullptr; - - /* -------------------------------------------------------------------- */ - /* Create a corresponding GDALDataset. */ - /* -------------------------------------------------------------------- */ - auto poDS = cpl::make_unique(); - - poDS->pszFilename = CPLStrdup(poOpenInfo->pszFilename); - poDS->SetMetadataItem("LAYER", pszLayer, nullptr); - 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. */ - /* -------------------------------------------------------------------- */ - std::swap(poDS->fpImage, poOpenInfo->fpL); - - poDS->adfGeoTransform[0] = dfXmin; - poDS->adfGeoTransform[1] = dfCellwidth; - poDS->adfGeoTransform[2] = dfXSkew; - poDS->adfGeoTransform[3] = dfYmax; - poDS->adfGeoTransform[4] = dfYSkew; - poDS->adfGeoTransform[5] = -dfCellheight; - - /* -------------------------------------------------------------------- */ - /* Create band information objects. */ - /* -------------------------------------------------------------------- */ - auto poBand = RawRasterBand::Create( - poDS.get(), 1, poDS->fpImage, 0, nPixelOffset, nPixelOffset * nCols, - eType, RawRasterBand::ByteOrder::ORDER_BIG_ENDIAN, - RawRasterBand::OwnFP::NO); - if (!poBand) - return nullptr; - poBand->SetNoDataValue(dfNoDataValue); - poDS->SetBand(1, std::move(poBand)); - - /* -------------------------------------------------------------------- */ - /* Initialize any PAM information. */ - /* -------------------------------------------------------------------- */ - poDS->SetDescription(poOpenInfo->pszFilename); - poDS->TryLoadXML(); - - /* -------------------------------------------------------------------- */ - /* Check for overviews. */ - /* -------------------------------------------------------------------- */ - poDS->oOvManager.Initialize(poDS.get(), poOpenInfo->pszFilename); - - return poDS.release(); -} - -/************************************************************************/ -/* CreateCopy() */ -/************************************************************************/ -GDALDataset *ARGDataset::CreateCopy(const char *pszFilename, - GDALDataset *poSrcDS, int /* bStrict */, - char ** /* papszOptions */, - GDALProgressFunc /* pfnProgress */, - void * /*pProgressData */) -{ - if (!GDALIsDriverDeprecatedForGDAL39StillEnabled("ARG")) - return nullptr; - - const int nBands = poSrcDS->GetRasterCount(); - if (nBands != 1) - { - CPLError(CE_Failure, CPLE_NotSupported, - "ARG driver doesn't support %d bands. Must be 1 band.", - nBands); - return nullptr; - } - - CPLString pszDataType; - int nPixelOffset = 0; - - GDALDataType 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 nullptr; - } - else if (eType == GDT_Int16) - { - pszDataType = "int16"; - nPixelOffset = 2; - } - else if (eType == GDT_Int32) - { - pszDataType = "int32"; - nPixelOffset = 4; - } - else if (eType == GDT_Int64) - { - pszDataType = "int64"; - nPixelOffset = 8; - } - 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_UInt64) - { - pszDataType = "uint64"; - nPixelOffset = 8; - } - else if (eType == GDT_Float32) - { - pszDataType = "float32"; - nPixelOffset = 4; - } - else if (eType == GDT_Float64) - { - pszDataType = "float64"; - nPixelOffset = 8; - } - - double adfTransform[6]; - poSrcDS->GetGeoTransform(adfTransform); - - const char *pszWKT = poSrcDS->GetProjectionRef(); - OGRSpatialReference oSRS; - OGRErr nErr = oSRS.importFromWkt(pszWKT); - if (nErr != OGRERR_NONE) - { - CPLError(CE_Failure, CPLE_NotSupported, - "Cannot import spatial reference WKT from source dataset."); - return nullptr; - } - - int nSrs = 0; - if (oSRS.GetAuthorityCode("PROJCS") != nullptr) - { - nSrs = atoi(oSRS.GetAuthorityCode("PROJCS")); - } - else if (oSRS.GetAuthorityCode("GEOGCS") != nullptr) - { - 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. */ - /********************************************************************/ - const CPLString osJSONFilename = GetJsonFilename(pszFilename); - - json_object *poJSONObject = json_object_new_object(); - - char **pszTokens = poSrcDS->GetMetadata(); - const char *pszLayer = CSLFetchNameValue(pszTokens, "LAYER"); - - if (pszLayer == nullptr) - { - // 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)); - - const int nXSize = poSrcDS->GetRasterXSize(); - const int nYSize = poSrcDS->GetRasterYSize(); - - // 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(const_cast(osJSONFilename.c_str()), - poJSONObject) < 0) - { - CPLError(CE_Failure, CPLE_NotSupported, - "ARG driver can't write companion file."); - - json_object_put(poJSONObject); - poJSONObject = nullptr; - - return nullptr; - } - - json_object_put(poJSONObject); - poJSONObject = nullptr; - - VSILFILE *fpImage = VSIFOpenL(pszFilename, "wb"); - if (fpImage == nullptr) - { - CPLError(CE_Failure, CPLE_NotSupported, - "ARG driver can't create data file %s.", pszFilename); - - // remove JSON file - VSIUnlink(osJSONFilename.c_str()); - - return nullptr; - } - - // only 1 raster band - GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand(1); - - auto poDstBand = - RawRasterBand::Create(fpImage, 0, nPixelOffset, nPixelOffset * nXSize, - eType, RawRasterBand::ByteOrder::ORDER_BIG_ENDIAN, - nXSize, nYSize, RawRasterBand::OwnFP::YES); - if (!poDstBand) - return nullptr; - poDstBand->SetAccess(GA_Update); - - int nXBlockSize, nYBlockSize; - poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize); - - void *pabyData = VSI_MALLOC2_VERBOSE(nXBlockSize, nPixelOffset); - if (!pabyData) - return nullptr; - - // 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; - - CPLErr eErr = poSrcBand->RasterIO( - GF_Read, nXBlock * nXBlockSize, - nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, - nXBlockSize, 1, eType, 0, 0, nullptr); - - if (eErr != CE_None) - { - CPLError(CE_Failure, CPLE_AppDefined, "Error reading."); - - CPLFree(pabyData); - - return nullptr; - } - - eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize, - nYBlock * nYBlockSize + nYScanline, - nXValid, 1, pabyData, nXBlockSize, 1, - eType, 0, 0, nullptr); - - if (eErr != CE_None) - { - CPLError(CE_Failure, CPLE_AppDefined, "Error writing."); - - CPLFree(pabyData); - - return nullptr; - } - } - } - } - - CPLFree(pabyData); - poDstBand.reset(); - - return GDALDataset::FromHandle(GDALOpen(pszFilename, GA_ReadOnly)); -} - -/************************************************************************/ -/* GDALRegister_ARG() */ -/************************************************************************/ - -void GDALRegister_ARG() -{ - if (GDALGetDriverByName("ARG") != nullptr) - return; - - GDALDriver *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, "drivers/raster/arg.html"); - poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); - - poDriver->pfnIdentify = ARGDataset::Identify; - poDriver->pfnOpen = ARGDataset::Open; - poDriver->pfnCreateCopy = ARGDataset::CreateCopy; - - GetGDALDriverManager()->RegisterDriver(poDriver); -} diff --git a/frmts/drivers.ini b/frmts/drivers.ini index ec782d9b076a..60f1cd32ea70 100644 --- a/frmts/drivers.ini +++ b/frmts/drivers.ini @@ -130,7 +130,6 @@ ROI_PAC RRASTER BYN NOAA_B -ARG RIK USGSDEM GXF diff --git a/frmts/gdalallregister.cpp b/frmts/gdalallregister.cpp index 145e6b260897..72f7bce8745a 100644 --- a/frmts/gdalallregister.cpp +++ b/frmts/gdalallregister.cpp @@ -485,10 +485,6 @@ void CPL_STDCALL GDALAllRegister() GDALRegister_NSIDCbin(); #endif -#ifdef FRMT_arg - GDALRegister_ARG(); -#endif - /* -------------------------------------------------------------------- */ /* Our test for the following is weak or expensive so we try */ /* them last. */ diff --git a/gcore/gdal_frmts.h b/gcore/gdal_frmts.h index 4c98ad2c1eec..331811e1f712 100644 --- a/gcore/gdal_frmts.h +++ b/gcore/gdal_frmts.h @@ -169,7 +169,6 @@ void CPL_DLL GDALRegister_WEBP(void); void CPL_DLL GDALRegister_ZMap(void); void CPL_DLL GDALRegister_NGSGEOID(void); void CPL_DLL GDALRegister_MBTiles(void); -void CPL_DLL GDALRegister_ARG(void); void CPL_DLL GDALRegister_IRIS(void); void CPL_DLL GDALRegister_KRO(void); void CPL_DLL GDALRegister_KEA(void);