diff --git a/frmts/gdalallregister.cpp b/frmts/gdalallregister.cpp index 2547286b3a55..9466132a9f71 100644 --- a/frmts/gdalallregister.cpp +++ b/frmts/gdalallregister.cpp @@ -203,6 +203,9 @@ void CPL_STDCALL GDALAllRegister() #if defined(DEFERRED_MONGODBV3_DRIVER) DeclareDeferredOGRMongoDBv3Plugin(); #endif +#if defined(DEFERRED_MRF_DRIVER) + DeclareDeferredMRFPlugin(); +#endif #if defined(DEFERRED_MRSID_DRIVER) DeclareDeferredMrSIDPlugin(); #endif diff --git a/frmts/mrf/CMakeLists.txt b/frmts/mrf/CMakeLists.txt index ede61b07e276..041f5d3a7f90 100644 --- a/frmts/mrf/CMakeLists.txt +++ b/frmts/mrf/CMakeLists.txt @@ -10,9 +10,22 @@ add_gdal_driver( Packer_RLE.cpp Packer_RLE.h Tif_band.cpp + CORE_SOURCES + mrfdrivercore.cpp PLUGIN_CAPABLE_IF "NOT GDAL_USE_JPEG_INTERNAL;NOT GDAL_USE_JPEG12_INTERNAL;NOT GDAL_USE_LERC_INTERNAL;NOT GDAL_USE_PNG_INTERNAL;NOT GDAL_USE_TIFF_INTERNAL;NOT GDAL_USE_ZLIB_INTERNAL" ) + +if(TARGET gdal_MRF_core) + if (GDAL_USE_LERC OR GDAL_USE_LERC_INTERNAL) + target_compile_definitions(gdal_MRF_core PRIVATE -DLERC) + endif() +endif() + +if(NOT TARGET gdal_MRF) + return() +endif() + gdal_standard_includes(gdal_MRF) if (GDAL_USE_JPEG OR GDAL_USE_JPEG_INTERNAL) diff --git a/frmts/mrf/marfa.h b/frmts/mrf/marfa.h index 4e0db05ff3e3..5206634f5107 100644 --- a/frmts/mrf/marfa.h +++ b/frmts/mrf/marfa.h @@ -364,7 +364,6 @@ class MRFDataset final : public GDALPamDataset virtual ~MRFDataset(); static GDALDataset *Open(GDALOpenInfo *); - static int Identify(GDALOpenInfo *); static GDALDataset *CreateCopy(const char *pszFilename, GDALDataset *poSrcDS, int bStrict, diff --git a/frmts/mrf/marfa_dataset.cpp b/frmts/mrf/marfa_dataset.cpp index 16f7442c81f2..9717cba197c4 100644 --- a/frmts/mrf/marfa_dataset.cpp +++ b/frmts/mrf/marfa_dataset.cpp @@ -59,6 +59,7 @@ ****************************************************************************/ #include "marfa.h" +#include "mrfdrivercore.h" #include "cpl_multiproc.h" /* for CPLSleep() */ #include "gdal_priv.h" #include @@ -519,37 +520,6 @@ void MRFDataset::SetMaxValue(const char *pszVal) list2vec(vMax, pszVal); } -/** - *\brief Idenfity a MRF file, lightweight - * - * Lightweight test, otherwise Open gets called. - * - */ -int MRFDataset::Identify(GDALOpenInfo *poOpenInfo) -{ - if (STARTS_WITH(poOpenInfo->pszFilename, "")) - return TRUE; - - CPLString fn(poOpenInfo->pszFilename); - if (fn.find(":MRF:") != string::npos) - return TRUE; - - if (poOpenInfo->nHeaderBytes < 10) - return FALSE; - - const char *pszHeader = reinterpret_cast(poOpenInfo->pabyHeader); - fn.assign(pszHeader, pszHeader + poOpenInfo->nHeaderBytes); - if (STARTS_WITH(fn, "")) - return TRUE; - -#if defined(LERC) // Could be single LERC tile - if (LERC_Band::IsLerc1(fn) || LERC_Band::IsLerc2(fn)) - return TRUE; -#endif - - return FALSE; -} - /** * *\brief Read the XML config tree, from file @@ -615,7 +585,7 @@ static int getnum(const vector &theStringVector, const char prefix, */ GDALDataset *MRFDataset::Open(GDALOpenInfo *poOpenInfo) { - if (!Identify(poOpenInfo)) + if (!MRFDriverIdentify(poOpenInfo)) return nullptr; CPLXMLNode *config = nullptr; diff --git a/frmts/mrf/mrf_util.cpp b/frmts/mrf/mrf_util.cpp index 3505d3d10ec1..ccff8412ab1f 100644 --- a/frmts/mrf/mrf_util.cpp +++ b/frmts/mrf/mrf_util.cpp @@ -51,6 +51,7 @@ #include #include #include +#include "mrfdrivercore.h" // LERC and QB3 only work on little endian machines #if defined(WORDS_BIGENDIAN) @@ -582,20 +583,11 @@ USING_NAMESPACE_MRF void GDALRegister_mrf() { - if (GDALGetDriverByName("MRF") != nullptr) + if (GDALGetDriverByName(DRIVER_NAME) != nullptr) return; GDALDriver *driver = new GDALDriver(); - driver->SetDescription("MRF"); - driver->SetMetadataItem(GDAL_DMD_LONGNAME, "Meta Raster Format"); - driver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/marfa.html"); - driver->SetMetadataItem(GDAL_DMD_EXTENSION, "mrf"); - driver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); - driver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); - - // These will need to be revisited, do we support complex data types too? - driver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES, - "Byte UInt16 Int16 Int32 UInt32 Float32 Float64"); + MRFDriverSetCommonMetadata(driver); driver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST, @@ -694,17 +686,7 @@ void GDALRegister_mrf() "'/>" "\n"); - driver->SetMetadataItem( - GDAL_DMD_OPENOPTIONLIST, - "" - " "); - driver->pfnOpen = MRFDataset::Open; - driver->pfnIdentify = MRFDataset::Identify; driver->pfnCreateCopy = MRFDataset::CreateCopy; driver->pfnCreate = MRFDataset::Create; driver->pfnDelete = MRFDataset::Delete; diff --git a/frmts/mrf/mrfdrivercore.cpp b/frmts/mrf/mrfdrivercore.cpp new file mode 100644 index 000000000000..ebf9dc732b83 --- /dev/null +++ b/frmts/mrf/mrfdrivercore.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2002-2012, California Institute of Technology. + * All rights reserved. Based on Government Sponsored Research under contracts + * NAS7-1407 and/or NAS7-03001. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the California Institute of Technology (Caltech), + * its operating division the Jet Propulsion Laboratory (JPL), the National + * Aeronautics and Space Administration (NASA), nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright 2014-2021 Esri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Functions used by the driver, should have prototypes in the header file + * + * Author: Lucian Plesea + */ + +#include "mrfdrivercore.h" +#include "cpl_string.h" + +#if defined(LERC) +static bool IsLerc1(const char *s) +{ + static const char L1sig[] = "CntZImage "; + return !strncmp(s, L1sig, sizeof(L1sig) - 1); +} +static bool IsLerc2(const char *s) +{ + static const char L2sig[] = "Lerc2 "; + return !strncmp(s, L2sig, sizeof(L2sig) - 1); +} +#endif + +/************************************************************************/ +/* MRFDriverIdentify() */ +/************************************************************************/ + +/** + *\brief Idenfity a MRF file, lightweight + * + * Lightweight test, otherwise Open gets called. + * + */ +int MRFDriverIdentify(GDALOpenInfo *poOpenInfo) + +{ + if (STARTS_WITH(poOpenInfo->pszFilename, "")) + return TRUE; + + CPLString fn(poOpenInfo->pszFilename); + if (fn.find(":MRF:") != std::string::npos) + return TRUE; + + if (poOpenInfo->nHeaderBytes < 10) + return FALSE; + + const char *pszHeader = reinterpret_cast(poOpenInfo->pabyHeader); + fn.assign(pszHeader, pszHeader + poOpenInfo->nHeaderBytes); + if (STARTS_WITH(fn, "")) + return TRUE; + +#if defined(LERC) // Could be single LERC tile + if (IsLerc1(fn) || IsLerc2(fn)) + return TRUE; +#endif + + return FALSE; +} + +/************************************************************************/ +/* MRFDriverSetCommonMetadata() */ +/************************************************************************/ + +void MRFDriverSetCommonMetadata(GDALDriver *poDriver) +{ + poDriver->SetDescription(DRIVER_NAME); + poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Meta Raster Format"); + poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/marfa.html"); + poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "mrf"); + poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); + + poDriver->SetMetadataItem( + GDAL_DMD_OPENOPTIONLIST, + "" + " "); + + // These will need to be revisited, do we support complex data types too? + poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES, + "Byte UInt16 Int16 Int32 UInt32 Float32 Float64"); + + poDriver->pfnIdentify = MRFDriverIdentify; + poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); + poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); +} + +/************************************************************************/ +/* DeclareDeferredMRFPlugin() */ +/************************************************************************/ + +#ifdef PLUGIN_FILENAME +void DeclareDeferredMRFPlugin() +{ + if (GDALGetDriverByName(DRIVER_NAME) != nullptr) + { + return; + } + auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); + MRFDriverSetCommonMetadata(poDriver); + GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); +} +#endif diff --git a/frmts/mrf/mrfdrivercore.h b/frmts/mrf/mrfdrivercore.h new file mode 100644 index 000000000000..87035d7ec207 --- /dev/null +++ b/frmts/mrf/mrfdrivercore.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2002-2012, California Institute of Technology. + * All rights reserved. Based on Government Sponsored Research under contracts + * NAS7-1407 and/or NAS7-03001. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the California Institute of Technology (Caltech), + * its operating division the Jet Propulsion Laboratory (JPL), the National + * Aeronautics and Space Administration (NASA), nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright 2014-2021 Esri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Functions used by the driver, should have prototypes in the header file + * + * Author: Lucian Plesea + */ + +#ifndef MRFDRIVERCORE_H +#define MRFDRIVERCORE_H + +#include "gdal_priv.h" + +constexpr const char *DRIVER_NAME = "MRF"; + +int CPL_DLL MRFDriverIdentify(GDALOpenInfo *poOpenInfo); + +void CPL_DLL MRFDriverSetCommonMetadata(GDALDriver *poDriver); + +#endif diff --git a/gcore/gdal_frmts.h b/gcore/gdal_frmts.h index b3885ff73fbf..03851f39a2dc 100644 --- a/gcore/gdal_frmts.h +++ b/gcore/gdal_frmts.h @@ -201,6 +201,7 @@ void CPL_DLL GDALRegister_WMTS(void); void CPL_DLL GDALRegister_SAFE(void); void CPL_DLL GDALRegister_SENTINEL2(void); void CPL_DLL GDALRegister_mrf(void); +void DeclareDeferredMRFPlugin(void); void CPL_DLL GDALRegister_RRASTER(void); void CPL_DLL GDALRegister_Derived(void); void CPL_DLL GDALRegister_JP2Lura(void);